Browse Source

Cleanup

rpm
J. King 4 years ago
parent
commit
b5f118e8cb
  1. 2
      lib/Database.php
  2. 2
      lib/Feed.php
  3. 8
      lib/Misc/Date.php
  4. 28
      tests/cases/CLI/TestCLI.php
  5. 32
      tests/cases/Conf/TestConf.php
  6. 120
      tests/cases/Database/SeriesArticle.php
  7. 20
      tests/cases/Database/SeriesCleanup.php
  8. 20
      tests/cases/Database/SeriesFeed.php
  9. 92
      tests/cases/Database/SeriesFolder.php
  10. 96
      tests/cases/Database/SeriesLabel.php
  11. 14
      tests/cases/Database/SeriesMeta.php
  12. 12
      tests/cases/Database/SeriesMiscellany.php
  13. 24
      tests/cases/Database/SeriesSession.php
  14. 92
      tests/cases/Database/SeriesSubscription.php
  15. 100
      tests/cases/Database/SeriesTag.php
  16. 24
      tests/cases/Database/SeriesToken.php
  17. 38
      tests/cases/Database/SeriesUser.php
  18. 4
      tests/cases/Database/TestDatabase.php
  19. 70
      tests/cases/Db/BaseDriver.php
  20. 18
      tests/cases/Db/BaseResult.php
  21. 18
      tests/cases/Db/BaseStatement.php
  22. 24
      tests/cases/Db/BaseUpdate.php
  23. 2
      tests/cases/Db/MySQL/TestCreation.php
  24. 2
      tests/cases/Db/MySQL/TestStatement.php
  25. 2
      tests/cases/Db/MySQLPDO/TestCreation.php
  26. 4
      tests/cases/Db/PostgreSQL/TestCreation.php
  27. 4
      tests/cases/Db/PostgreSQLPDO/TestCreation.php
  28. 26
      tests/cases/Db/SQLite3/TestCreation.php
  29. 26
      tests/cases/Db/SQLite3PDO/TestCreation.php
  30. 14
      tests/cases/Db/TestResultAggregate.php
  31. 10
      tests/cases/Db/TestResultEmpty.php
  32. 6
      tests/cases/Db/TestTransaction.php
  33. 14
      tests/cases/Exception/TestException.php
  34. 34
      tests/cases/Feed/TestFeed.php
  35. 18
      tests/cases/Feed/TestFetching.php
  36. 4
      tests/cases/ImportExport/TestFile.php
  37. 16
      tests/cases/ImportExport/TestImportExport.php
  38. 8
      tests/cases/ImportExport/TestOPML.php
  39. 10
      tests/cases/Lang/TestBasic.php
  40. 24
      tests/cases/Lang/TestComplex.php
  41. 24
      tests/cases/Lang/TestErrors.php
  42. 12
      tests/cases/Misc/TestContext.php
  43. 8
      tests/cases/Misc/TestDate.php
  44. 2
      tests/cases/Misc/TestHTTP.php
  45. 16
      tests/cases/Misc/TestQuery.php
  46. 6
      tests/cases/Misc/TestURL.php
  47. 16
      tests/cases/Misc/TestValueInfo.php
  48. 28
      tests/cases/REST/Fever/TestAPI.php
  49. 6
      tests/cases/REST/Fever/TestUser.php
  50. 60
      tests/cases/REST/NextcloudNews/TestV1_2.php
  51. 8
      tests/cases/REST/NextcloudNews/TestVersions.php
  52. 18
      tests/cases/REST/TestREST.php
  53. 74
      tests/cases/REST/TinyTinyRSS/TestAPI.php
  54. 4
      tests/cases/REST/TinyTinyRSS/TestIcon.php
  55. 2
      tests/cases/REST/TinyTinyRSS/TestSearch.php
  56. 8
      tests/cases/Service/TestSerial.php
  57. 12
      tests/cases/Service/TestService.php
  58. 8
      tests/cases/Service/TestSubprocess.php
  59. 4
      tests/cases/TestArsse.php
  60. 22
      tests/cases/User/TestInternal.php
  61. 22
      tests/cases/User/TestUser.php

2
lib/Database.php

@ -932,7 +932,7 @@ class Database {
} }
/** Returns the time at which any of a user's subscriptions (or a specific subscription) was last refreshed, as a DateTimeImmutable object */ /** Returns the time at which any of a user's subscriptions (or a specific subscription) was last refreshed, as a DateTimeImmutable object */
public function subscriptionRefreshed(string $user, int $id = null): ?\DateTimeInterface { public function subscriptionRefreshed(string $user, int $id = null): ?\DateTimeImmutable {
if (!Arsse::$user->authorize($user, __FUNCTION__)) { if (!Arsse::$user->authorize($user, __FUNCTION__)) {
throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
} }

2
lib/Feed.php

@ -390,7 +390,7 @@ class Feed {
return $offset; return $offset;
} }
protected function computeLastModified(): ?\DateTimeInterface { protected function computeLastModified(): ?\DateTimeImmutable {
if (!$this->modified) { if (!$this->modified) {
return $this->lastModified; // @codeCoverageIgnore return $this->lastModified; // @codeCoverageIgnore
} }

8
lib/Misc/Date.php

@ -21,19 +21,19 @@ class Date {
return $out; return $out;
} }
public static function normalize($date, string $inFormat = null): ?\DateTimeInterface { public static function normalize($date, string $inFormat = null): ?\DateTimeImmutable {
return ValueInfo::normalize($date, ValueInfo::T_DATE, $inFormat); return ValueInfo::normalize($date, ValueInfo::T_DATE, $inFormat);
} }
public static function add($interval, $date = "now"): ?\DateTimeInterface { public static function add($interval, $date = "now"): ?\DateTimeImmutable {
return self::modify("add", $interval, $date); return self::modify("add", $interval, $date);
} }
public static function sub($interval, $date = "now"): ?\DateTimeInterface { public static function sub($interval, $date = "now"): ?\DateTimeImmutable {
return self::modify("sub", $interval, $date); return self::modify("sub", $interval, $date);
} }
protected static function modify(string $func, $interval, $date): ?\DateTimeInterface { protected static function modify(string $func, $interval, $date): ?\DateTimeImmutable {
$date = self::normalize($date); $date = self::normalize($date);
$interval = (!$interval instanceof \DateInterval) ? ValueInfo::normalize($interval, ValueInfo::T_INTERVAL) : $interval; $interval = (!$interval instanceof \DateInterval) ? ValueInfo::normalize($interval, ValueInfo::T_INTERVAL) : $interval;
return $date ? $date->$func($interval) : null; return $date ? $date->$func($interval) : null;

28
tests/cases/CLI/TestCLI.php

@ -35,13 +35,13 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame($exitStatus, $cli->dispatch($argv)); $this->assertSame($exitStatus, $cli->dispatch($argv));
} }
public function testPrintVersion():void { public function testPrintVersion(): void {
$this->assertConsole($this->cli, "arsse.php --version", 0, Arsse::VERSION); $this->assertConsole($this->cli, "arsse.php --version", 0, Arsse::VERSION);
\Phake::verify($this->cli, \Phake::times(0))->loadConf; \Phake::verify($this->cli, \Phake::times(0))->loadConf;
} }
/** @dataProvider provideHelpText */ /** @dataProvider provideHelpText */
public function testPrintHelp(string $cmd, string $name):void { public function testPrintHelp(string $cmd, string $name): void {
$this->assertConsole($this->cli, $cmd, 0, str_replace("arsse.php", $name, CLI::USAGE)); $this->assertConsole($this->cli, $cmd, 0, str_replace("arsse.php", $name, CLI::USAGE));
\Phake::verify($this->cli, \Phake::times(0))->loadConf; \Phake::verify($this->cli, \Phake::times(0))->loadConf;
} }
@ -57,7 +57,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
]; ];
} }
public function testStartTheDaemon():void { public function testStartTheDaemon(): void {
$srv = \Phake::mock(Service::class); $srv = \Phake::mock(Service::class);
\Phake::when($srv)->watch->thenReturn(new \DateTimeImmutable); \Phake::when($srv)->watch->thenReturn(new \DateTimeImmutable);
\Phake::when($this->cli)->getInstance(Service::class)->thenReturn($srv); \Phake::when($this->cli)->getInstance(Service::class)->thenReturn($srv);
@ -67,7 +67,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
\Phake::verify($this->cli)->getInstance(Service::class); \Phake::verify($this->cli)->getInstance(Service::class);
} }
public function testRefreshAllFeeds():void { public function testRefreshAllFeeds(): void {
$srv = \Phake::mock(Service::class); $srv = \Phake::mock(Service::class);
\Phake::when($srv)->watch->thenReturn(new \DateTimeImmutable); \Phake::when($srv)->watch->thenReturn(new \DateTimeImmutable);
\Phake::when($this->cli)->getInstance(Service::class)->thenReturn($srv); \Phake::when($this->cli)->getInstance(Service::class)->thenReturn($srv);
@ -78,7 +78,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideFeedUpdates */ /** @dataProvider provideFeedUpdates */
public function testRefreshAFeed(string $cmd, int $exitStatus, string $output):void { public function testRefreshAFeed(string $cmd, int $exitStatus, string $output): void {
Arsse::$db = \Phake::mock(Database::class); Arsse::$db = \Phake::mock(Database::class);
\Phake::when(Arsse::$db)->feedUpdate(1, true)->thenReturn(true); \Phake::when(Arsse::$db)->feedUpdate(1, true)->thenReturn(true);
\Phake::when(Arsse::$db)->feedUpdate(2, true)->thenThrow(new \JKingWeb\Arsse\Feed\Exception("http://example.com/", new \PicoFeed\Client\InvalidUrlException)); \Phake::when(Arsse::$db)->feedUpdate(2, true)->thenThrow(new \JKingWeb\Arsse\Feed\Exception("http://example.com/", new \PicoFeed\Client\InvalidUrlException));
@ -95,7 +95,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideDefaultConfigurationSaves */ /** @dataProvider provideDefaultConfigurationSaves */
public function testSaveTheDefaultConfiguration(string $cmd, int $exitStatus, string $file):void { public function testSaveTheDefaultConfiguration(string $cmd, int $exitStatus, string $file): void {
$conf = \Phake::mock(Conf::class); $conf = \Phake::mock(Conf::class);
\Phake::when($conf)->exportFile("php://output", true)->thenReturn(true); \Phake::when($conf)->exportFile("php://output", true)->thenReturn(true);
\Phake::when($conf)->exportFile("good.conf", true)->thenReturn(true); \Phake::when($conf)->exportFile("good.conf", true)->thenReturn(true);
@ -116,7 +116,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideUserList */ /** @dataProvider provideUserList */
public function testListUsers(string $cmd, array $list, int $exitStatus, string $output):void { public function testListUsers(string $cmd, array $list, int $exitStatus, string $output): void {
// FIXME: Phake is somehow unable to mock the User class correctly, so we use PHPUnit's mocks instead // FIXME: Phake is somehow unable to mock the User class correctly, so we use PHPUnit's mocks instead
Arsse::$user = $this->createMock(User::class); Arsse::$user = $this->createMock(User::class);
Arsse::$user->method("list")->willReturn($list); Arsse::$user->method("list")->willReturn($list);
@ -135,7 +135,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideUserAdditions */ /** @dataProvider provideUserAdditions */
public function testAddAUser(string $cmd, int $exitStatus, string $output):void { public function testAddAUser(string $cmd, int $exitStatus, string $output): void {
// FIXME: Phake is somehow unable to mock the User class correctly, so we use PHPUnit's mocks instead // FIXME: Phake is somehow unable to mock the User class correctly, so we use PHPUnit's mocks instead
Arsse::$user = $this->createMock(User::class); Arsse::$user = $this->createMock(User::class);
Arsse::$user->method("add")->will($this->returnCallback(function($user, $pass = null) { Arsse::$user->method("add")->will($this->returnCallback(function($user, $pass = null) {
@ -158,7 +158,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideUserAuthentication */ /** @dataProvider provideUserAuthentication */
public function testAuthenticateAUser(string $cmd, int $exitStatus, string $output):void { public function testAuthenticateAUser(string $cmd, int $exitStatus, string $output): void {
// FIXME: Phake is somehow unable to mock the User class correctly, so we use PHPUnit's mocks instead // FIXME: Phake is somehow unable to mock the User class correctly, so we use PHPUnit's mocks instead
Arsse::$user = $this->createMock(User::class); Arsse::$user = $this->createMock(User::class);
Arsse::$user->method("auth")->will($this->returnCallback(function($user, $pass) { Arsse::$user->method("auth")->will($this->returnCallback(function($user, $pass) {
@ -192,7 +192,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideUserRemovals */ /** @dataProvider provideUserRemovals */
public function testRemoveAUser(string $cmd, int $exitStatus, string $output):void { public function testRemoveAUser(string $cmd, int $exitStatus, string $output): void {
// FIXME: Phake is somehow unable to mock the User class correctly, so we use PHPUnit's mocks instead // FIXME: Phake is somehow unable to mock the User class correctly, so we use PHPUnit's mocks instead
Arsse::$user = $this->createMock(User::class); Arsse::$user = $this->createMock(User::class);
Arsse::$user->method("remove")->will($this->returnCallback(function($user) { Arsse::$user->method("remove")->will($this->returnCallback(function($user) {
@ -212,7 +212,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideUserPasswordChanges */ /** @dataProvider provideUserPasswordChanges */
public function testChangeAUserPassword(string $cmd, int $exitStatus, string $output):void { public function testChangeAUserPassword(string $cmd, int $exitStatus, string $output): void {
$passwordChange = function($user, $pass = null) { $passwordChange = function($user, $pass = null) {
switch ($user) { switch ($user) {
case "jane.doe@example.com": case "jane.doe@example.com":
@ -242,7 +242,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideUserPasswordClearings */ /** @dataProvider provideUserPasswordClearings */
public function testClearAUserPassword(string $cmd, int $exitStatus, string $output):void { public function testClearAUserPassword(string $cmd, int $exitStatus, string $output): void {
$passwordClear = function($user) { $passwordClear = function($user) {
switch ($user) { switch ($user) {
case "jane.doe@example.com": case "jane.doe@example.com":
@ -270,7 +270,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideOpmlExports */ /** @dataProvider provideOpmlExports */
public function testExportToOpml(string $cmd, int $exitStatus, string $file, string $user, bool $flat):void { public function testExportToOpml(string $cmd, int $exitStatus, string $file, string $user, bool $flat): void {
$opml = \Phake::mock(OPML::class); $opml = \Phake::mock(OPML::class);
\Phake::when($opml)->exportFile("php://output", $user, $flat)->thenReturn(true); \Phake::when($opml)->exportFile("php://output", $user, $flat)->thenReturn(true);
\Phake::when($opml)->exportFile("good.opml", $user, $flat)->thenReturn(true); \Phake::when($opml)->exportFile("good.opml", $user, $flat)->thenReturn(true);
@ -311,7 +311,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideOpmlImports */ /** @dataProvider provideOpmlImports */
public function testImportFromOpml(string $cmd, int $exitStatus, string $file, string $user, bool $flat, bool $replace):void { public function testImportFromOpml(string $cmd, int $exitStatus, string $file, string $user, bool $flat, bool $replace): void {
$opml = \Phake::mock(OPML::class); $opml = \Phake::mock(OPML::class);
\Phake::when($opml)->importFile("php://input", $user, $flat, $replace)->thenReturn(true); \Phake::when($opml)->importFile("php://input", $user, $flat, $replace)->thenReturn(true);
\Phake::when($opml)->importFile("good.opml", $user, $flat, $replace)->thenReturn(true); \Phake::when($opml)->importFile("good.opml", $user, $flat, $replace)->thenReturn(true);

32
tests/cases/Conf/TestConf.php

@ -38,12 +38,12 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
self::clearData(); self::clearData();
} }
public function testLoadDefaultValues():void { public function testLoadDefaultValues(): void {
$this->assertInstanceOf(Conf::class, new Conf); $this->assertInstanceOf(Conf::class, new Conf);
} }
/** @depends testLoadDefaultValues */ /** @depends testLoadDefaultValues */
public function testImportFromArray():void { public function testImportFromArray(): void {
$arr = [ $arr = [
'lang' => "xx", 'lang' => "xx",
'purgeFeeds' => "P2D", 'purgeFeeds' => "P2D",
@ -54,7 +54,7 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @depends testImportFromArray */ /** @depends testImportFromArray */
public function testImportFromFile():void { public function testImportFromFile(): void {
$conf = new Conf; $conf = new Conf;
$conf->importFile(self::$path."confGood"); $conf->importFile(self::$path."confGood");
$this->assertEquals("xx", $conf->lang); $this->assertEquals("xx", $conf->lang);
@ -63,43 +63,43 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @depends testImportFromFile */ /** @depends testImportFromFile */
public function testImportFromMissingFile():void { public function testImportFromMissingFile(): void {
$this->assertException("fileMissing", "Conf"); $this->assertException("fileMissing", "Conf");
$conf = new Conf(self::$path."confMissing"); $conf = new Conf(self::$path."confMissing");
} }
/** @depends testImportFromFile */ /** @depends testImportFromFile */
public function testImportFromEmptyFile():void { public function testImportFromEmptyFile(): void {
$this->assertException("fileCorrupt", "Conf"); $this->assertException("fileCorrupt", "Conf");
$conf = new Conf(self::$path."confEmpty"); $conf = new Conf(self::$path."confEmpty");
} }
/** @depends testImportFromFile */ /** @depends testImportFromFile */
public function testImportFromFileWithoutReadPermission():void { public function testImportFromFileWithoutReadPermission(): void {
$this->assertException("fileUnreadable", "Conf"); $this->assertException("fileUnreadable", "Conf");
$conf = new Conf(self::$path."confUnreadable"); $conf = new Conf(self::$path."confUnreadable");
} }
/** @depends testImportFromFile */ /** @depends testImportFromFile */
public function testImportFromFileWhichIsNotAnArray():void { public function testImportFromFileWhichIsNotAnArray(): void {
$this->assertException("fileCorrupt", "Conf"); $this->assertException("fileCorrupt", "Conf");
$conf = new Conf(self::$path."confNotArray"); $conf = new Conf(self::$path."confNotArray");
} }
/** @depends testImportFromFile */ /** @depends testImportFromFile */
public function testImportFromFileWhichIsNotPhp():void { public function testImportFromFileWhichIsNotPhp(): void {
$this->assertException("fileCorrupt", "Conf"); $this->assertException("fileCorrupt", "Conf");
// this should not print the output of the non-PHP file // this should not print the output of the non-PHP file
$conf = new Conf(self::$path."confNotPHP"); $conf = new Conf(self::$path."confNotPHP");
} }
/** @depends testImportFromFile */ /** @depends testImportFromFile */
public function testImportFromCorruptFile():void { public function testImportFromCorruptFile(): void {
$this->assertException("fileCorrupt", "Conf"); $this->assertException("fileCorrupt", "Conf");
$conf = new Conf(self::$path."confCorrupt"); $conf = new Conf(self::$path."confCorrupt");
} }
public function testImportBogusValue():void { public function testImportBogusValue(): void {
$arr = [ $arr = [
'dbAutoUpdate' => "yes, please", 'dbAutoUpdate' => "yes, please",
]; ];
@ -108,7 +108,7 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
$conf->import($arr); $conf->import($arr);
} }
public function testImportBogusDriver():void { public function testImportBogusDriver(): void {
$arr = [ $arr = [
'dbDriver' => "this driver does not exist", 'dbDriver' => "this driver does not exist",
]; ];
@ -117,7 +117,7 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
$conf->import($arr); $conf->import($arr);
} }
public function testExportToArray():void { public function testExportToArray(): void {
$conf = new Conf; $conf = new Conf;
$conf->lang = ["en", "fr"]; // should not be exported: not scalar $conf->lang = ["en", "fr"]; // should not be exported: not scalar
$conf->dbSQLite3File = "test.db"; // should be exported: value changed $conf->dbSQLite3File = "test.db"; // should be exported: value changed
@ -138,7 +138,7 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
/** @depends testExportToArray /** @depends testExportToArray
* @depends testImportFromFile */ * @depends testImportFromFile */
public function testExportToFile():void { public function testExportToFile(): void {
$conf = new Conf; $conf = new Conf;
$conf->lang = ["en", "fr"]; // should not be exported: not scalar $conf->lang = ["en", "fr"]; // should not be exported: not scalar
$conf->dbSQLite3File = "test.db"; // should be exported: value changed $conf->dbSQLite3File = "test.db"; // should be exported: value changed
@ -159,19 +159,19 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @depends testExportToFile */ /** @depends testExportToFile */
public function testExportToStdout():void { public function testExportToStdout(): void {
$conf = new Conf(self::$path."confGood"); $conf = new Conf(self::$path."confGood");
$conf->exportFile(self::$path."confGood"); $conf->exportFile(self::$path."confGood");
$this->expectOutputString(file_get_contents(self::$path."confGood")); $this->expectOutputString(file_get_contents(self::$path."confGood"));
$conf->exportFile("php://output"); $conf->exportFile("php://output");
} }
public function testExportToFileWithoutWritePermission():void { public function testExportToFileWithoutWritePermission(): void {
$this->assertException("fileUnwritable", "Conf"); $this->assertException("fileUnwritable", "Conf");
(new Conf)->exportFile(self::$path."confUnreadable"); (new Conf)->exportFile(self::$path."confUnreadable");
} }
public function testExportToFileWithoutCreatePermission():void { public function testExportToFileWithoutCreatePermission(): void {
$this->assertException("fileUncreatable", "Conf"); $this->assertException("fileUncreatable", "Conf");
(new Conf)->exportFile(self::$path."confForbidden/conf"); (new Conf)->exportFile(self::$path."confForbidden/conf");
} }

120
tests/cases/Database/SeriesArticle.php

@ -13,7 +13,7 @@ use JKingWeb\Arsse\Misc\Date;
use JKingWeb\Arsse\Misc\ValueInfo; use JKingWeb\Arsse\Misc\ValueInfo;
trait SeriesArticle { trait SeriesArticle {
protected function setUpSeriesArticle():void { protected function setUpSeriesArticle(): void {
$this->data = [ $this->data = [
'arsse_users' => [ 'arsse_users' => [
'columns' => [ 'columns' => [
@ -408,12 +408,12 @@ trait SeriesArticle {
$this->user = "john.doe@example.net"; $this->user = "john.doe@example.net";
} }
protected function tearDownSeriesArticle():void { protected function tearDownSeriesArticle(): void {
unset($this->data, $this->matches, $this->fields, $this->checkTables, $this->user); unset($this->data, $this->matches, $this->fields, $this->checkTables, $this->user);
} }
/** @dataProvider provideContextMatches */ /** @dataProvider provideContextMatches */
public function testListArticlesCheckingContext(Context $c, array $exp):void { public function testListArticlesCheckingContext(Context $c, array $exp): void {
$ids = array_column($ids = Arsse::$db->articleList("john.doe@example.com", $c, ["id"], ["id"])->getAll(), "id"); $ids = array_column($ids = Arsse::$db->articleList("john.doe@example.com", $c, ["id"], ["id"])->getAll(), "id");
sort($ids); sort($ids);
sort($exp); sort($exp);
@ -516,7 +516,7 @@ trait SeriesArticle {
]; ];
} }
public function testRetrieveArticleIdsForEditions():void { public function testRetrieveArticleIdsForEditions(): void {
$exp = [ $exp = [
1 => 1, 1 => 1,
2 => 2, 2 => 2,
@ -553,17 +553,17 @@ trait SeriesArticle {
$this->assertEquals($exp, Arsse::$db->editionArticle(...range(1, 1001))); $this->assertEquals($exp, Arsse::$db->editionArticle(...range(1, 1001)));
} }
public function testListArticlesOfAMissingFolder():void { public function testListArticlesOfAMissingFolder(): void {
$this->assertException("idMissing", "Db", "ExceptionInput"); $this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->articleList($this->user, (new Context)->folder(1)); Arsse::$db->articleList($this->user, (new Context)->folder(1));
} }
public function testListArticlesOfAMissingSubscription():void { public function testListArticlesOfAMissingSubscription(): void {
$this->assertException("idMissing", "Db", "ExceptionInput"); $this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->articleList($this->user, (new Context)->subscription(1)); Arsse::$db->articleList($this->user, (new Context)->subscription(1));
} }
public function testListArticlesCheckingProperties():void { public function testListArticlesCheckingProperties(): void {
$this->user = "john.doe@example.org"; $this->user = "john.doe@example.org";
// check that the different fieldset groups return the expected columns // check that the different fieldset groups return the expected columns
foreach ($this->fields as $column) { foreach ($this->fields as $column) {
@ -577,7 +577,7 @@ trait SeriesArticle {
} }
/** @dataProvider provideOrderedLists */ /** @dataProvider provideOrderedLists */
public function testListArticlesCheckingOrder(array $sortCols, array $exp):void { public function testListArticlesCheckingOrder(array $sortCols, array $exp): void {
$act = ValueInfo::normalize(array_column(iterator_to_array(Arsse::$db->articleList("john.doe@example.com", null, ["id"], $sortCols)), "id"), ValueInfo::T_INT | ValueInfo::M_ARRAY); $act = ValueInfo::normalize(array_column(iterator_to_array(Arsse::$db->articleList("john.doe@example.com", null, ["id"], $sortCols)), "id"), ValueInfo::T_INT | ValueInfo::M_ARRAY);
$this->assertSame($exp, $act); $this->assertSame($exp, $act);
} }
@ -595,17 +595,17 @@ trait SeriesArticle {
]; ];
} }
public function testListArticlesWithoutAuthority():void { public function testListArticlesWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleList($this->user); Arsse::$db->articleList($this->user);
} }
public function testMarkNothing():void { public function testMarkNothing(): void {
$this->assertSame(0, Arsse::$db->articleMark($this->user, [])); $this->assertSame(0, Arsse::$db->articleMark($this->user, []));
} }
public function testMarkAllArticlesUnread():void { public function testMarkAllArticlesUnread(): void {
Arsse::$db->articleMark($this->user, ['read'=>false]); Arsse::$db->articleMark($this->user, ['read'=>false]);
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -616,7 +616,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkAllArticlesRead():void { public function testMarkAllArticlesRead(): void {
Arsse::$db->articleMark($this->user, ['read'=>true]); Arsse::$db->articleMark($this->user, ['read'=>true]);
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -631,7 +631,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkAllArticlesUnstarred():void { public function testMarkAllArticlesUnstarred(): void {
Arsse::$db->articleMark($this->user, ['starred'=>false]); Arsse::$db->articleMark($this->user, ['starred'=>false]);
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -642,7 +642,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkAllArticlesStarred():void { public function testMarkAllArticlesStarred(): void {
Arsse::$db->articleMark($this->user, ['starred'=>true]); Arsse::$db->articleMark($this->user, ['starred'=>true]);
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -657,7 +657,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkAllArticlesUnreadAndUnstarred():void { public function testMarkAllArticlesUnreadAndUnstarred(): void {
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>false]); Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>false]);
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -671,7 +671,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkAllArticlesReadAndStarred():void { public function testMarkAllArticlesReadAndStarred(): void {
Arsse::$db->articleMark($this->user, ['read'=>true,'starred'=>true]); Arsse::$db->articleMark($this->user, ['read'=>true,'starred'=>true]);
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -689,7 +689,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkAllArticlesUnreadAndStarred():void { public function testMarkAllArticlesUnreadAndStarred(): void {
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true]); Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true]);
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -707,7 +707,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkAllArticlesReadAndUnstarred():void { public function testMarkAllArticlesReadAndUnstarred(): void {
Arsse::$db->articleMark($this->user, ['read'=>true,'starred'=>false]); Arsse::$db->articleMark($this->user, ['read'=>true,'starred'=>false]);
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -725,7 +725,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testSetNoteForAllArticles():void { public function testSetNoteForAllArticles(): void {
Arsse::$db->articleMark($this->user, ['note'=>"New note"]); Arsse::$db->articleMark($this->user, ['note'=>"New note"]);
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -744,7 +744,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkATreeFolder():void { public function testMarkATreeFolder(): void {
Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->folder(7)); Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->folder(7));
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -755,7 +755,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkALeafFolder():void { public function testMarkALeafFolder(): void {
Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->folder(8)); Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->folder(8));
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -764,12 +764,12 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkAMissingFolder():void { public function testMarkAMissingFolder(): void {
$this->assertException("idMissing", "Db", "ExceptionInput"); $this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->folder(42)); Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->folder(42));
} }
public function testMarkASubscription():void { public function testMarkASubscription(): void {
Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->subscription(13)); Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->subscription(13));
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -778,12 +778,12 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkAMissingSubscription():void { public function testMarkAMissingSubscription(): void {
$this->assertException("idMissing", "Db", "ExceptionInput"); $this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->folder(2112)); Arsse::$db->articleMark($this->user, ['read'=>true], (new Context)->folder(2112));
} }
public function testMarkAnArticle():void { public function testMarkAnArticle(): void {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->article(20)); Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->article(20));
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -792,7 +792,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkMultipleArticles():void { public function testMarkMultipleArticles(): void {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->articles([2,4,7,20])); Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->articles([2,4,7,20]));
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -802,7 +802,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkMultipleArticlessUnreadAndStarred():void { public function testMarkMultipleArticlessUnreadAndStarred(): void {
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->articles([2,4,7,20])); Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->articles([2,4,7,20]));
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -815,16 +815,16 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkTooManyMultipleArticles():void { public function testMarkTooManyMultipleArticles(): void {
$this->assertSame(7, Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->articles(range(1, Database::LIMIT_SET_SIZE * 3)))); $this->assertSame(7, Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->articles(range(1, Database::LIMIT_SET_SIZE * 3))));
} }
public function testMarkAMissingArticle():void { public function testMarkAMissingArticle(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->article(1)); Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->article(1));
} }
public function testMarkAnEdition():void { public function testMarkAnEdition(): void {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->edition(1001)); Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->edition(1001));
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -833,7 +833,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkMultipleEditions():void { public function testMarkMultipleEditions(): void {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->editions([2,4,7,20])); Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->editions([2,4,7,20]));
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -843,13 +843,13 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkMultipleMissingEditions():void { public function testMarkMultipleMissingEditions(): void {
$this->assertSame(0, Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->editions([500,501]))); $this->assertSame(0, Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->editions([500,501])));
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkMultipleEditionsUnread():void { public function testMarkMultipleEditionsUnread(): void {
Arsse::$db->articleMark($this->user, ['read'=>false], (new Context)->editions([2,4,7,1001])); Arsse::$db->articleMark($this->user, ['read'=>false], (new Context)->editions([2,4,7,1001]));
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -860,7 +860,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkMultipleEditionsUnreadWithStale():void { public function testMarkMultipleEditionsUnreadWithStale(): void {
Arsse::$db->articleMark($this->user, ['read'=>false], (new Context)->editions([2,4,7,20])); Arsse::$db->articleMark($this->user, ['read'=>false], (new Context)->editions([2,4,7,20]));
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -869,7 +869,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkMultipleEditionsUnreadAndStarredWithStale():void { public function testMarkMultipleEditionsUnreadAndStarredWithStale(): void {
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->editions([2,4,7,20])); Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->editions([2,4,7,20]));
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -881,17 +881,17 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkTooManyMultipleEditions():void { public function testMarkTooManyMultipleEditions(): void {
$this->assertSame(7, Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->editions(range(1, 51)))); $this->assertSame(7, Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->editions(range(1, 51))));
} }
public function testMarkAStaleEditionUnread():void { public function testMarkAStaleEditionUnread(): void {
Arsse::$db->articleMark($this->user, ['read'=>false], (new Context)->edition(20)); // no changes occur Arsse::$db->articleMark($this->user, ['read'=>false], (new Context)->edition(20)); // no changes occur
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkAStaleEditionStarred():void { public function testMarkAStaleEditionStarred(): void {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->edition(20)); Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->edition(20));
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -900,7 +900,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkAStaleEditionUnreadAndStarred():void { public function testMarkAStaleEditionUnreadAndStarred(): void {
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->edition(20)); // only starred is changed Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>true], (new Context)->edition(20)); // only starred is changed
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -909,18 +909,18 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkAStaleEditionUnreadAndUnstarred():void { public function testMarkAStaleEditionUnreadAndUnstarred(): void {
Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>false], (new Context)->edition(20)); // no changes occur Arsse::$db->articleMark($this->user, ['read'=>false,'starred'=>false], (new Context)->edition(20)); // no changes occur
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkAMissingEdition():void { public function testMarkAMissingEdition(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->edition(2)); Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->edition(2));
} }
public function testMarkByOldestEdition():void { public function testMarkByOldestEdition(): void {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->oldestEdition(19)); Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->oldestEdition(19));
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -931,7 +931,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkByLatestEdition():void { public function testMarkByLatestEdition(): void {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->latestEdition(20)); Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->latestEdition(20));
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -944,7 +944,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkByLastMarked():void { public function testMarkByLastMarked(): void {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->markedSince('2017-01-01T00:00:00Z')); Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->markedSince('2017-01-01T00:00:00Z'));
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -955,7 +955,7 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkByNotLastMarked():void { public function testMarkByNotLastMarked(): void {
Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->notMarkedSince('2000-01-01T00:00:00Z')); Arsse::$db->articleMark($this->user, ['starred'=>true], (new Context)->notMarkedSince('2000-01-01T00:00:00Z'));
$now = Date::transform(time(), "sql"); $now = Date::transform(time(), "sql");
$state = $this->primeExpectations($this->data, $this->checkTables); $state = $this->primeExpectations($this->data, $this->checkTables);
@ -964,55 +964,55 @@ trait SeriesArticle {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMarkArticlesWithoutAuthority():void { public function testMarkArticlesWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleMark($this->user, ['read'=>false]); Arsse::$db->articleMark($this->user, ['read'=>false]);
} }
public function testCountArticles():void { public function testCountArticles(): void {
$this->assertSame(2, Arsse::$db->articleCount("john.doe@example.com", (new Context)->starred(true))); $this->assertSame(2, Arsse::$db->articleCount("john.doe@example.com", (new Context)->starred(true)));
$this->assertSame(4, Arsse::$db->articleCount("john.doe@example.com", (new Context)->folder(1))); $this->assertSame(4, Arsse::$db->articleCount("john.doe@example.com", (new Context)->folder(1)));
$this->assertSame(0, Arsse::$db->articleCount("jane.doe@example.com", (new Context)->starred(true))); $this->assertSame(0, Arsse::$db->articleCount("jane.doe@example.com", (new Context)->starred(true)));
$this->assertSame(10, Arsse::$db->articleCount("john.doe@example.com", (new Context)->articles(range(1, Database::LIMIT_SET_SIZE * 3)))); $this->assertSame(10, Arsse::$db->articleCount("john.doe@example.com", (new Context)->articles(range(1, Database::LIMIT_SET_SIZE * 3))));
} }
public function testCountArticlesWithoutAuthority():void { public function testCountArticlesWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleCount($this->user); Arsse::$db->articleCount($this->user);
} }
public function testFetchStarredCounts():void { public function testFetchStarredCounts(): void {
$exp1 = ['total' => 2, 'unread' => 1, 'read' => 1]; $exp1 = ['total' => 2, 'unread' => 1, 'read' => 1];
$exp2 = ['total' => 0, 'unread' => 0, 'read' => 0]; $exp2 = ['total' => 0, 'unread' => 0, 'read' => 0];
$this->assertEquals($exp1, Arsse::$db->articleStarred("john.doe@example.com")); $this->assertEquals($exp1, Arsse::$db->articleStarred("john.doe@example.com"));
$this->assertEquals($exp2, Arsse::$db->articleStarred("jane.doe@example.com")); $this->assertEquals($exp2, Arsse::$db->articleStarred("jane.doe@example.com"));
} }
public function testFetchStarredCountsWithoutAuthority():void { public function testFetchStarredCountsWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleStarred($this->user); Arsse::$db->articleStarred($this->user);
} }
public function testFetchLatestEdition():void { public function testFetchLatestEdition(): void {
$this->assertSame(1001, Arsse::$db->editionLatest($this->user)); $this->assertSame(1001, Arsse::$db->editionLatest($this->user));
$this->assertSame(4, Arsse::$db->editionLatest($this->user, (new Context)->subscription(12))); $this->assertSame(4, Arsse::$db->editionLatest($this->user, (new Context)->subscription(12)));
} }
public function testFetchLatestEditionOfMissingSubscription():void { public function testFetchLatestEditionOfMissingSubscription(): void {
$this->assertException("idMissing", "Db", "ExceptionInput"); $this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->editionLatest($this->user, (new Context)->subscription(1)); Arsse::$db->editionLatest($this->user, (new Context)->subscription(1));
} }
public function testFetchLatestEditionWithoutAuthority():void { public function testFetchLatestEditionWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->editionLatest($this->user); Arsse::$db->editionLatest($this->user);
} }
public function testListTheLabelsOfAnArticle():void { public function testListTheLabelsOfAnArticle(): void {
$this->assertEquals([1,2], Arsse::$db->articleLabelsGet("john.doe@example.com", 1)); $this->assertEquals([1,2], Arsse::$db->articleLabelsGet("john.doe@example.com", 1));
$this->assertEquals([2], Arsse::$db->articleLabelsGet("john.doe@example.com", 5)); $this->assertEquals([2], Arsse::$db->articleLabelsGet("john.doe@example.com", 5));
$this->assertEquals([], Arsse::$db->articleLabelsGet("john.doe@example.com", 2)); $this->assertEquals([], Arsse::$db->articleLabelsGet("john.doe@example.com", 2));
@ -1021,18 +1021,18 @@ trait SeriesArticle {
$this->assertEquals([], Arsse::$db->articleLabelsGet("john.doe@example.com", 2, true)); $this->assertEquals([], Arsse::$db->articleLabelsGet("john.doe@example.com", 2, true));
} }
public function testListTheLabelsOfAMissingArticle():void { public function testListTheLabelsOfAMissingArticle(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->articleLabelsGet($this->user, 101); Arsse::$db->articleLabelsGet($this->user, 101);
} }
public function testListTheLabelsOfAnArticleWithoutAuthority():void { public function testListTheLabelsOfAnArticleWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleLabelsGet("john.doe@example.com", 1); Arsse::$db->articleLabelsGet("john.doe@example.com", 1);
} }
public function testListTheCategoriesOfAnArticle():void { public function testListTheCategoriesOfAnArticle(): void {
$exp = ["Fascinating", "Logical"]; $exp = ["Fascinating", "Logical"];
$this->assertSame($exp, Arsse::$db->articleCategoriesGet($this->user, 19)); $this->assertSame($exp, Arsse::$db->articleCategoriesGet($this->user, 19));
$exp = ["Interesting", "Logical"]; $exp = ["Interesting", "Logical"];
@ -1041,19 +1041,19 @@ trait SeriesArticle {
$this->assertSame($exp, Arsse::$db->articleCategoriesGet($this->user, 4)); $this->assertSame($exp, Arsse::$db->articleCategoriesGet($this->user, 4));
} }
public function testListTheCategoriesOfAMissingArticle():void { public function testListTheCategoriesOfAMissingArticle(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->articleCategoriesGet($this->user, 101); Arsse::$db->articleCategoriesGet($this->user, 101);
} }
public function testListTheCategoriesOfAnArticleWithoutAuthority():void { public function testListTheCategoriesOfAnArticleWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->articleCategoriesGet($this->user, 19); Arsse::$db->articleCategoriesGet($this->user, 19);
} }
/** @dataProvider provideArrayContextOptions */ /** @dataProvider provideArrayContextOptions */
public function testUseTooFewValuesInArrayContext(string $option):void { public function testUseTooFewValuesInArrayContext(string $option): void {
$this->assertException("tooShort", "Db", "ExceptionInput"); $this->assertException("tooShort", "Db", "ExceptionInput");
Arsse::$db->articleList($this->user, (new Context)->$option([])); Arsse::$db->articleList($this->user, (new Context)->$option([]));
} }

20
tests/cases/Database/SeriesCleanup.php

@ -9,7 +9,7 @@ namespace JKingWeb\Arsse\TestCase\Database;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
trait SeriesCleanup { trait SeriesCleanup {
protected function setUpSeriesCleanup():void { protected function setUpSeriesCleanup(): void {
// set up the configuration // set up the configuration
Arsse::$conf->import([ Arsse::$conf->import([
'userSessionTimeout' => "PT1H", 'userSessionTimeout' => "PT1H",
@ -147,11 +147,11 @@ trait SeriesCleanup {
]; ];
} }
protected function tearDownSeriesCleanup():void { protected function tearDownSeriesCleanup(): void {
unset($this->data); unset($this->data);
} }
public function testCleanUpOrphanedFeeds():void { public function testCleanUpOrphanedFeeds(): void {
Arsse::$db->feedCleanup(); Arsse::$db->feedCleanup();
$now = gmdate("Y-m-d H:i:s"); $now = gmdate("Y-m-d H:i:s");
$state = $this->primeExpectations($this->data, [ $state = $this->primeExpectations($this->data, [
@ -163,7 +163,7 @@ trait SeriesCleanup {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testCleanUpOrphanedFeedsWithUnlimitedRetention():void { public function testCleanUpOrphanedFeedsWithUnlimitedRetention(): void {
Arsse::$conf->import([ Arsse::$conf->import([
'purgeFeeds' => null, 'purgeFeeds' => null,
]); ]);
@ -177,7 +177,7 @@ trait SeriesCleanup {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testCleanUpOldArticlesWithStandardRetention():void { public function testCleanUpOldArticlesWithStandardRetention(): void {
Arsse::$db->articleCleanup(); Arsse::$db->articleCleanup();
$state = $this->primeExpectations($this->data, [ $state = $this->primeExpectations($this->data, [
'arsse_articles' => ["id"] 'arsse_articles' => ["id"]
@ -188,7 +188,7 @@ trait SeriesCleanup {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testCleanUpOldArticlesWithUnlimitedReadRetention():void { public function testCleanUpOldArticlesWithUnlimitedReadRetention(): void {
Arsse::$conf->import([ Arsse::$conf->import([
'purgeArticlesRead' => null, 'purgeArticlesRead' => null,
]); ]);
@ -202,7 +202,7 @@ trait SeriesCleanup {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testCleanUpOldArticlesWithUnlimitedUnreadRetention():void { public function testCleanUpOldArticlesWithUnlimitedUnreadRetention(): void {
Arsse::$conf->import([ Arsse::$conf->import([
'purgeArticlesUnread' => null, 'purgeArticlesUnread' => null,
]); ]);
@ -216,7 +216,7 @@ trait SeriesCleanup {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testCleanUpOldArticlesWithUnlimitedRetention():void { public function testCleanUpOldArticlesWithUnlimitedRetention(): void {
Arsse::$conf->import([ Arsse::$conf->import([
'purgeArticlesRead' => null, 'purgeArticlesRead' => null,
'purgeArticlesUnread' => null, 'purgeArticlesUnread' => null,
@ -228,7 +228,7 @@ trait SeriesCleanup {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testCleanUpExpiredSessions():void { public function testCleanUpExpiredSessions(): void {
Arsse::$db->sessionCleanup(); Arsse::$db->sessionCleanup();
$state = $this->primeExpectations($this->data, [ $state = $this->primeExpectations($this->data, [
'arsse_sessions' => ["id"] 'arsse_sessions' => ["id"]
@ -239,7 +239,7 @@ trait SeriesCleanup {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testCleanUpExpiredTokens():void { public function testCleanUpExpiredTokens(): void {
Arsse::$db->tokenCleanup(); Arsse::$db->tokenCleanup();
$state = $this->primeExpectations($this->data, [ $state = $this->primeExpectations($this->data, [
'arsse_tokens' => ["id", "class"] 'arsse_tokens' => ["id", "class"]

20
tests/cases/Database/SeriesFeed.php

@ -9,7 +9,7 @@ namespace JKingWeb\Arsse\TestCase\Database;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
trait SeriesFeed { trait SeriesFeed {
protected function setUpSeriesFeed():void { protected function setUpSeriesFeed(): void {
// set up the test data // set up the test data
$past = gmdate("Y-m-d H:i:s", strtotime("now - 1 minute")); $past = gmdate("Y-m-d H:i:s", strtotime("now - 1 minute"));
$future = gmdate("Y-m-d H:i:s", strtotime("now + 1 minute")); $future = gmdate("Y-m-d H:i:s", strtotime("now + 1 minute"));
@ -160,15 +160,15 @@ trait SeriesFeed {
]; ];
} }
protected function tearDownSeriesFeed():void { protected function tearDownSeriesFeed(): void {
unset($this->data, $this->matches); unset($this->data, $this->matches);
} }
public function testListLatestItems():void { public function testListLatestItems(): void {
$this->assertResult($this->matches, Arsse::$db->feedMatchLatest(1, 2)); $this->assertResult($this->matches, Arsse::$db->feedMatchLatest(1, 2));
} }
public function testMatchItemsById():void { public function testMatchItemsById(): void {
$this->assertResult($this->matches, Arsse::$db->feedMatchIds(1, ['804e517d623390e71497982c77cf6823180342ebcd2e7d5e32da1e55b09dd180','db3e736c2c492f5def5c5da33ddcbea1824040e9ced2142069276b0a6e291a41'])); $this->assertResult($this->matches, Arsse::$db->feedMatchIds(1, ['804e517d623390e71497982c77cf6823180342ebcd2e7d5e32da1e55b09dd180','db3e736c2c492f5def5c5da33ddcbea1824040e9ced2142069276b0a6e291a41']));
foreach ($this->matches as $m) { foreach ($this->matches as $m) {
$exp = [$m]; $exp = [$m];
@ -179,7 +179,7 @@ trait SeriesFeed {
$this->assertResult([['id' => 1]], Arsse::$db->feedMatchIds(1, ['e433653cef2e572eee4215fa299a4a5af9137b2cefd6283c85bd69a32915beda'])); // this ID appears in both feed 1 and feed 2; only one result should be returned $this->assertResult([['id' => 1]], Arsse::$db->feedMatchIds(1, ['e433653cef2e572eee4215fa299a4a5af9137b2cefd6283c85bd69a32915beda'])); // this ID appears in both feed 1 and feed 2; only one result should be returned
} }
public function testUpdateAFeed():void { public function testUpdateAFeed(): void {
// update a valid feed with both new and changed items // update a valid feed with both new and changed items
Arsse::$db->feedUpdate(1); Arsse::$db->feedUpdate(1);
$now = gmdate("Y-m-d H:i:s"); $now = gmdate("Y-m-d H:i:s");
@ -219,22 +219,22 @@ trait SeriesFeed {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testUpdateAMissingFeed():void { public function testUpdateAMissingFeed(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->feedUpdate(2112); Arsse::$db->feedUpdate(2112);
} }
public function testUpdateAnInvalidFeed():void { public function testUpdateAnInvalidFeed(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->feedUpdate(-1); Arsse::$db->feedUpdate(-1);
} }
public function testUpdateAFeedThrowingExceptions():void { public function testUpdateAFeedThrowingExceptions(): void {
$this->assertException("invalidUrl", "Feed"); $this->assertException("invalidUrl", "Feed");
Arsse::$db->feedUpdate(3, true); Arsse::$db->feedUpdate(3, true);
} }
public function testUpdateAFeedWithEnclosuresAndCategories():void { public function testUpdateAFeedWithEnclosuresAndCategories(): void {
Arsse::$db->feedUpdate(5); Arsse::$db->feedUpdate(5);
$state = $this->primeExpectations($this->data, [ $state = $this->primeExpectations($this->data, [
'arsse_enclosures' => ["url","type"], 'arsse_enclosures' => ["url","type"],
@ -254,7 +254,7 @@ trait SeriesFeed {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testListStaleFeeds():void { public function testListStaleFeeds(): void {
$this->assertEquals([1,3,4], Arsse::$db->feedListStale()); $this->assertEquals([1,3,4], Arsse::$db->feedListStale());
Arsse::$db->feedUpdate(3); Arsse::$db->feedUpdate(3);
Arsse::$db->feedUpdate(4); Arsse::$db->feedUpdate(4);

92
tests/cases/Database/SeriesFolder.php

@ -9,7 +9,7 @@ namespace JKingWeb\Arsse\TestCase\Database;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
trait SeriesFolder { trait SeriesFolder {
protected function setUpSeriesFolder():void { protected function setUpSeriesFolder(): void {
$this->data = [ $this->data = [
'arsse_users' => [ 'arsse_users' => [
'columns' => [ 'columns' => [
@ -93,11 +93,11 @@ trait SeriesFolder {
]; ];
} }
protected function tearDownSeriesFolder():void { protected function tearDownSeriesFolder(): void {
unset($this->data); unset($this->data);
} }
public function testAddARootFolder():void { public function testAddARootFolder(): void {
$user = "john.doe@example.com"; $user = "john.doe@example.com";
$folderID = $this->nextID("arsse_folders"); $folderID = $this->nextID("arsse_folders");
$this->assertSame($folderID, Arsse::$db->folderAdd($user, ['name' => "Entertainment"])); $this->assertSame($folderID, Arsse::$db->folderAdd($user, ['name' => "Entertainment"]));
@ -107,12 +107,12 @@ trait SeriesFolder {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testAddADuplicateRootFolder():void { public function testAddADuplicateRootFolder(): void {
$this->assertException("constraintViolation", "Db", "ExceptionInput"); $this->assertException("constraintViolation", "Db", "ExceptionInput");
Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Politics"]); Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Politics"]);
} }
public function testAddANestedFolder():void { public function testAddANestedFolder(): void {
$user = "john.doe@example.com"; $user = "john.doe@example.com";
$folderID = $this->nextID("arsse_folders"); $folderID = $this->nextID("arsse_folders");
$this->assertSame($folderID, Arsse::$db->folderAdd($user, ['name' => "GNOME", 'parent' => 2])); $this->assertSame($folderID, Arsse::$db->folderAdd($user, ['name' => "GNOME", 'parent' => 2]));
@ -122,43 +122,43 @@ trait SeriesFolder {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testAddANestedFolderToAMissingParent():void { public function testAddANestedFolderToAMissingParent(): void {
$this->assertException("idMissing", "Db", "ExceptionInput"); $this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Sociology", 'parent' => 2112]); Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Sociology", 'parent' => 2112]);
} }
public function testAddANestedFolderToAnInvalidParent():void { public function testAddANestedFolderToAnInvalidParent(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Sociology", 'parent' => "stringFolderId"]); Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Sociology", 'parent' => "stringFolderId"]);
} }
public function testAddANestedFolderForTheWrongOwner():void { public function testAddANestedFolderForTheWrongOwner(): void {
$this->assertException("idMissing", "Db", "ExceptionInput"); $this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Sociology", 'parent' => 4]); // folder ID 4 belongs to Jane Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Sociology", 'parent' => 4]); // folder ID 4 belongs to Jane
} }
public function testAddAFolderWithAMissingName():void { public function testAddAFolderWithAMissingName(): void {
$this->assertException("missing", "Db", "ExceptionInput"); $this->assertException("missing", "Db", "ExceptionInput");
Arsse::$db->folderAdd("john.doe@example.com", []); Arsse::$db->folderAdd("john.doe@example.com", []);
} }
public function testAddAFolderWithABlankName():void { public function testAddAFolderWithABlankName(): void {
$this->assertException("missing", "Db", "ExceptionInput"); $this->assertException("missing", "Db", "ExceptionInput");
Arsse::$db->folderAdd("john.doe@example.com", ['name' => ""]); Arsse::$db->folderAdd("john.doe@example.com", ['name' => ""]);
} }
public function testAddAFolderWithAWhitespaceName():void { public function testAddAFolderWithAWhitespaceName(): void {
$this->assertException("whitespace", "Db", "ExceptionInput"); $this->assertException("whitespace", "Db", "ExceptionInput");
Arsse::$db->folderAdd("john.doe@example.com", ['name' => " "]); Arsse::$db->folderAdd("john.doe@example.com", ['name' => " "]);
} }
public function testAddAFolderWithoutAuthority():void { public function testAddAFolderWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Sociology"]); Arsse::$db->folderAdd("john.doe@example.com", ['name' => "Sociology"]);
} }
public function testListRootFolders():void { public function testListRootFolders(): void {
$exp = [ $exp = [
['id' => 5, 'name' => "Politics", 'parent' => null, 'children' => 0, 'feeds' => 2], ['id' => 5, 'name' => "Politics", 'parent' => null, 'children' => 0, 'feeds' => 2],
['id' => 1, 'name' => "Technology", 'parent' => null, 'children' => 2, 'feeds' => 1], ['id' => 1, 'name' => "Technology", 'parent' => null, 'children' => 2, 'feeds' => 1],
@ -175,7 +175,7 @@ trait SeriesFolder {
\Phake::verify(Arsse::$user)->authorize("admin@example.net", "folderList"); \Phake::verify(Arsse::$user)->authorize("admin@example.net", "folderList");
} }
public function testListFoldersRecursively():void { public function testListFoldersRecursively(): void {
$exp = [ $exp = [
['id' => 5, 'name' => "Politics", 'parent' => null, 'children' => 0, 'feeds' => 2], ['id' => 5, 'name' => "Politics", 'parent' => null, 'children' => 0, 'feeds' => 2],
['id' => 6, 'name' => "Politics", 'parent' => 2, 'children' => 0, 'feeds' => 1], ['id' => 6, 'name' => "Politics", 'parent' => 2, 'children' => 0, 'feeds' => 1],
@ -196,23 +196,23 @@ trait SeriesFolder {
\Phake::verify(Arsse::$user)->authorize("jane.doe@example.com", "folderList"); \Phake::verify(Arsse::$user)->authorize("jane.doe@example.com", "folderList");
} }
public function testListFoldersOfAMissingParent():void { public function testListFoldersOfAMissingParent(): void {
$this->assertException("idMissing", "Db", "ExceptionInput"); $this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->folderList("john.doe@example.com", 2112); Arsse::$db->folderList("john.doe@example.com", 2112);
} }
public function testListFoldersOfTheWrongOwner():void { public function testListFoldersOfTheWrongOwner(): void {
$this->assertException("idMissing", "Db", "ExceptionInput"); $this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->folderList("john.doe@example.com", 4); // folder ID 4 belongs to Jane Arsse::$db->folderList("john.doe@example.com", 4); // folder ID 4 belongs to Jane
} }
public function testListFoldersWithoutAuthority():void { public function testListFoldersWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->folderList("john.doe@example.com"); Arsse::$db->folderList("john.doe@example.com");
} }
public function testRemoveAFolder():void { public function testRemoveAFolder(): void {
$this->assertTrue(Arsse::$db->folderRemove("john.doe@example.com", 6)); $this->assertTrue(Arsse::$db->folderRemove("john.doe@example.com", 6));
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderRemove"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderRemove");
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]); $state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
@ -220,7 +220,7 @@ trait SeriesFolder {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testRemoveAFolderTree():void { public function testRemoveAFolderTree(): void {
$this->assertTrue(Arsse::$db->folderRemove("john.doe@example.com", 1)); $this->assertTrue(Arsse::$db->folderRemove("john.doe@example.com", 1));
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderRemove"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderRemove");
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]); $state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
@ -230,28 +230,28 @@ trait SeriesFolder {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testRemoveAMissingFolder():void { public function testRemoveAMissingFolder(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->folderRemove("john.doe@example.com", 2112); Arsse::$db->folderRemove("john.doe@example.com", 2112);
} }
public function testRemoveAnInvalidFolder():void { public function testRemoveAnInvalidFolder(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->folderRemove("john.doe@example.com", -1); Arsse::$db->folderRemove("john.doe@example.com", -1);
} }
public function testRemoveAFolderOfTheWrongOwner():void { public function testRemoveAFolderOfTheWrongOwner(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->folderRemove("john.doe@example.com", 4); // folder ID 4 belongs to Jane Arsse::$db->folderRemove("john.doe@example.com", 4); // folder ID 4 belongs to Jane
} }
public function testRemoveAFolderWithoutAuthority():void { public function testRemoveAFolderWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->folderRemove("john.doe@example.com", 1); Arsse::$db->folderRemove("john.doe@example.com", 1);
} }
public function testGetThePropertiesOfAFolder():void { public function testGetThePropertiesOfAFolder(): void {
$exp = [ $exp = [
'id' => 6, 'id' => 6,
'name' => "Politics", 'name' => "Politics",
@ -261,32 +261,32 @@ trait SeriesFolder {
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesGet"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesGet");
} }
public function testGetThePropertiesOfAMissingFolder():void { public function testGetThePropertiesOfAMissingFolder(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->folderPropertiesGet("john.doe@example.com", 2112); Arsse::$db->folderPropertiesGet("john.doe@example.com", 2112);
} }
public function testGetThePropertiesOfAnInvalidFolder():void { public function testGetThePropertiesOfAnInvalidFolder(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->folderPropertiesGet("john.doe@example.com", -1); Arsse::$db->folderPropertiesGet("john.doe@example.com", -1);
} }
public function testGetThePropertiesOfAFolderOfTheWrongOwner():void { public function testGetThePropertiesOfAFolderOfTheWrongOwner(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->folderPropertiesGet("john.doe@example.com", 4); // folder ID 4 belongs to Jane Arsse::$db->folderPropertiesGet("john.doe@example.com", 4); // folder ID 4 belongs to Jane
} }
public function testGetThePropertiesOfAFolderWithoutAuthority():void { public function testGetThePropertiesOfAFolderWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->folderPropertiesGet("john.doe@example.com", 1); Arsse::$db->folderPropertiesGet("john.doe@example.com", 1);
} }
public function testMakeNoChangesToAFolder():void { public function testMakeNoChangesToAFolder(): void {
$this->assertFalse(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, [])); $this->assertFalse(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, []));
} }
public function testRenameAFolder():void { public function testRenameAFolder(): void {
$this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['name' => "Opinion"])); $this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['name' => "Opinion"]));
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesSet"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesSet");
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]); $state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
@ -294,26 +294,26 @@ trait SeriesFolder {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testRenameTheRootFolder():void { public function testRenameTheRootFolder(): void {
$this->assertFalse(Arsse::$db->folderPropertiesSet("john.doe@example.com", null, ['name' => "Opinion"])); $this->assertFalse(Arsse::$db->folderPropertiesSet("john.doe@example.com", null, ['name' => "Opinion"]));
} }
public function testRenameAFolderToTheEmptyString():void { public function testRenameAFolderToTheEmptyString(): void {
$this->assertException("missing", "Db", "ExceptionInput"); $this->assertException("missing", "Db", "ExceptionInput");
$this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['name' => ""])); $this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['name' => ""]));
} }
public function testRenameAFolderToWhitespaceOnly():void { public function testRenameAFolderToWhitespaceOnly(): void {
$this->assertException("whitespace", "Db", "ExceptionInput"); $this->assertException("whitespace", "Db", "ExceptionInput");
$this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['name' => " "])); $this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['name' => " "]));
} }
public function testRenameAFolderToAnInvalidValue():void { public function testRenameAFolderToAnInvalidValue(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
$this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['name' => []])); $this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['name' => []]));
} }
public function testMoveAFolder():void { public function testMoveAFolder(): void {
$this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['parent' => 5])); $this->assertTrue(Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['parent' => 5]));
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesSet"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "folderPropertiesSet");
$state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]); $state = $this->primeExpectations($this->data, ['arsse_folders' => ['id','owner', 'parent', 'name']]);
@ -321,57 +321,57 @@ trait SeriesFolder {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMoveTheRootFolder():void { public function testMoveTheRootFolder(): void {
$this->assertException("circularDependence", "Db", "ExceptionInput"); $this->assertException("circularDependence", "Db", "ExceptionInput");
Arsse::$db->folderPropertiesSet("john.doe@example.com", 0, ['parent' => 1]); Arsse::$db->folderPropertiesSet("john.doe@example.com", 0, ['parent' => 1]);
} }
public function testMoveAFolderToItsDescendant():void { public function testMoveAFolderToItsDescendant(): void {
$this->assertException("circularDependence", "Db", "ExceptionInput"); $this->assertException("circularDependence", "Db", "ExceptionInput");
Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => 3]); Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => 3]);
} }
public function testMoveAFolderToItself():void { public function testMoveAFolderToItself(): void {
$this->assertException("circularDependence", "Db", "ExceptionInput"); $this->assertException("circularDependence", "Db", "ExceptionInput");
Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => 1]); Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => 1]);
} }
public function testMoveAFolderToAMissingParent():void { public function testMoveAFolderToAMissingParent(): void {
$this->assertException("idMissing", "Db", "ExceptionInput"); $this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => 2112]); Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => 2112]);
} }
public function testMoveAFolderToAnInvalidParent():void { public function testMoveAFolderToAnInvalidParent(): void {
$this->assertException("idMissing", "Db", "ExceptionInput"); $this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => "ThisFolderDoesNotExist"]); Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => "ThisFolderDoesNotExist"]);
} }
public function testCauseAFolderCollision():void { public function testCauseAFolderCollision(): void {
$this->assertException("constraintViolation", "Db", "ExceptionInput"); $this->assertException("constraintViolation", "Db", "ExceptionInput");
Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['parent' => null]); Arsse::$db->folderPropertiesSet("john.doe@example.com", 6, ['parent' => null]);
} }
public function testCauseACompoundFolderCollision():void { public function testCauseACompoundFolderCollision(): void {
$this->assertException("constraintViolation", "Db", "ExceptionInput"); $this->assertException("constraintViolation", "Db", "ExceptionInput");
Arsse::$db->folderPropertiesSet("john.doe@example.com", 3, ['parent' => null, 'name' => "Technology"]); Arsse::$db->folderPropertiesSet("john.doe@example.com", 3, ['parent' => null, 'name' => "Technology"]);
} }
public function testSetThePropertiesOfAMissingFolder():void { public function testSetThePropertiesOfAMissingFolder(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->folderPropertiesSet("john.doe@example.com", 2112, ['parent' => null]); Arsse::$db->folderPropertiesSet("john.doe@example.com", 2112, ['parent' => null]);
} }
public function testSetThePropertiesOfAnInvalidFolder():void { public function testSetThePropertiesOfAnInvalidFolder(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->folderPropertiesSet("john.doe@example.com", -1, ['parent' => null]); Arsse::$db->folderPropertiesSet("john.doe@example.com", -1, ['parent' => null]);
} }
public function testSetThePropertiesOfAFolderForTheWrongOwner():void { public function testSetThePropertiesOfAFolderForTheWrongOwner(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->folderPropertiesSet("john.doe@example.com", 4, ['parent' => null]); // folder ID 4 belongs to Jane Arsse::$db->folderPropertiesSet("john.doe@example.com", 4, ['parent' => null]); // folder ID 4 belongs to Jane
} }
public function testSetThePropertiesOfAFolderWithoutAuthority():void { public function testSetThePropertiesOfAFolderWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => null]); Arsse::$db->folderPropertiesSet("john.doe@example.com", 1, ['parent' => null]);

96
tests/cases/Database/SeriesLabel.php

@ -11,7 +11,7 @@ use JKingWeb\Arsse\Database;
use JKingWeb\Arsse\Context\Context; use JKingWeb\Arsse\Context\Context;
trait SeriesLabel { trait SeriesLabel {
protected function setUpSeriesLabel():void { protected function setUpSeriesLabel(): void {
$this->data = [ $this->data = [
'arsse_users' => [ 'arsse_users' => [
'columns' => [ 'columns' => [
@ -244,11 +244,11 @@ trait SeriesLabel {
$this->user = "john.doe@example.com"; $this->user = "john.doe@example.com";
} }
protected function tearDownSeriesLabel():void { protected function tearDownSeriesLabel(): void {
unset($this->data, $this->checkLabels, $this->checkMembers, $this->user); unset($this->data, $this->checkLabels, $this->checkMembers, $this->user);
} }
public function testAddALabel():void { public function testAddALabel(): void {
$user = "john.doe@example.com"; $user = "john.doe@example.com";
$labelID = $this->nextID("arsse_labels"); $labelID = $this->nextID("arsse_labels");
$this->assertSame($labelID, Arsse::$db->labelAdd($user, ['name' => "Entertaining"])); $this->assertSame($labelID, Arsse::$db->labelAdd($user, ['name' => "Entertaining"]));
@ -258,33 +258,33 @@ trait SeriesLabel {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testAddADuplicateLabel():void { public function testAddADuplicateLabel(): void {
$this->assertException("constraintViolation", "Db", "ExceptionInput"); $this->assertException("constraintViolation", "Db", "ExceptionInput");
Arsse::$db->labelAdd("john.doe@example.com", ['name' => "Interesting"]); Arsse::$db->labelAdd("john.doe@example.com", ['name' => "Interesting"]);
} }
public function testAddALabelWithAMissingName():void { public function testAddALabelWithAMissingName(): void {
$this->assertException("missing", "Db", "ExceptionInput"); $this->assertException("missing", "Db", "ExceptionInput");
Arsse::$db->labelAdd("john.doe@example.com", []); Arsse::$db->labelAdd("john.doe@example.com", []);
} }
public function testAddALabelWithABlankName():void { public function testAddALabelWithABlankName(): void {
$this->assertException("missing", "Db", "ExceptionInput"); $this->assertException("missing", "Db", "ExceptionInput");
Arsse::$db->labelAdd("john.doe@example.com", ['name' => ""]); Arsse::$db->labelAdd("john.doe@example.com", ['name' => ""]);
} }
public function testAddALabelWithAWhitespaceName():void { public function testAddALabelWithAWhitespaceName(): void {
$this->assertException("whitespace", "Db", "ExceptionInput"); $this->assertException("whitespace", "Db", "ExceptionInput");
Arsse::$db->labelAdd("john.doe@example.com", ['name' => " "]); Arsse::$db->labelAdd("john.doe@example.com", ['name' => " "]);
} }
public function testAddALabelWithoutAuthority():void { public function testAddALabelWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->labelAdd("john.doe@example.com", ['name' => "Boring"]); Arsse::$db->labelAdd("john.doe@example.com", ['name' => "Boring"]);
} }
public function testListLabels():void { public function testListLabels(): void {
$exp = [ $exp = [
['id' => 2, 'name' => "Fascinating", 'articles' => 3, 'read' => 1], ['id' => 2, 'name' => "Fascinating", 'articles' => 3, 'read' => 1],
['id' => 1, 'name' => "Interesting", 'articles' => 2, 'read' => 2], ['id' => 1, 'name' => "Interesting", 'articles' => 2, 'read' => 2],
@ -300,13 +300,13 @@ trait SeriesLabel {
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelList"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelList");
} }
public function testListLabelsWithoutAuthority():void { public function testListLabelsWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->labelList("john.doe@example.com"); Arsse::$db->labelList("john.doe@example.com");
} }
public function testRemoveALabel():void { public function testRemoveALabel(): void {
$this->assertTrue(Arsse::$db->labelRemove("john.doe@example.com", 1)); $this->assertTrue(Arsse::$db->labelRemove("john.doe@example.com", 1));
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelRemove"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelRemove");
$state = $this->primeExpectations($this->data, $this->checkLabels); $state = $this->primeExpectations($this->data, $this->checkLabels);
@ -314,7 +314,7 @@ trait SeriesLabel {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testRemoveALabelByName():void { public function testRemoveALabelByName(): void {
$this->assertTrue(Arsse::$db->labelRemove("john.doe@example.com", "Interesting", true)); $this->assertTrue(Arsse::$db->labelRemove("john.doe@example.com", "Interesting", true));
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelRemove"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelRemove");
$state = $this->primeExpectations($this->data, $this->checkLabels); $state = $this->primeExpectations($this->data, $this->checkLabels);
@ -322,33 +322,33 @@ trait SeriesLabel {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testRemoveAMissingLabel():void { public function testRemoveAMissingLabel(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->labelRemove("john.doe@example.com", 2112); Arsse::$db->labelRemove("john.doe@example.com", 2112);
} }
public function testRemoveAnInvalidLabel():void { public function testRemoveAnInvalidLabel(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->labelRemove("john.doe@example.com", -1); Arsse::$db->labelRemove("john.doe@example.com", -1);
} }
public function testRemoveAnInvalidLabelByName():void { public function testRemoveAnInvalidLabelByName(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->labelRemove("john.doe@example.com", [], true); Arsse::$db->labelRemove("john.doe@example.com", [], true);
} }
public function testRemoveALabelOfTheWrongOwner():void { public function testRemoveALabelOfTheWrongOwner(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->labelRemove("john.doe@example.com", 3); // label ID 3 belongs to Jane Arsse::$db->labelRemove("john.doe@example.com", 3); // label ID 3 belongs to Jane
} }
public function testRemoveALabelWithoutAuthority():void { public function testRemoveALabelWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->labelRemove("john.doe@example.com", 1); Arsse::$db->labelRemove("john.doe@example.com", 1);
} }
public function testGetThePropertiesOfALabel():void { public function testGetThePropertiesOfALabel(): void {
$exp = [ $exp = [
'id' => 2, 'id' => 2,
'name' => "Fascinating", 'name' => "Fascinating",
@ -360,37 +360,37 @@ trait SeriesLabel {
\Phake::verify(Arsse::$user, \Phake::times(2))->authorize("john.doe@example.com", "labelPropertiesGet"); \Phake::verify(Arsse::$user, \Phake::times(2))->authorize("john.doe@example.com", "labelPropertiesGet");
} }
public function testGetThePropertiesOfAMissingLabel():void { public function testGetThePropertiesOfAMissingLabel(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->labelPropertiesGet("john.doe@example.com", 2112); Arsse::$db->labelPropertiesGet("john.doe@example.com", 2112);
} }
public function testGetThePropertiesOfAnInvalidLabel():void { public function testGetThePropertiesOfAnInvalidLabel(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->labelPropertiesGet("john.doe@example.com", -1); Arsse::$db->labelPropertiesGet("john.doe@example.com", -1);
} }
public function testGetThePropertiesOfAnInvalidLabelByName():void { public function testGetThePropertiesOfAnInvalidLabelByName(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->labelPropertiesGet("john.doe@example.com", [], true); Arsse::$db->labelPropertiesGet("john.doe@example.com", [], true);
} }
public function testGetThePropertiesOfALabelOfTheWrongOwner():void { public function testGetThePropertiesOfALabelOfTheWrongOwner(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->labelPropertiesGet("john.doe@example.com", 3); // label ID 3 belongs to Jane Arsse::$db->labelPropertiesGet("john.doe@example.com", 3); // label ID 3 belongs to Jane
} }
public function testGetThePropertiesOfALabelWithoutAuthority():void { public function testGetThePropertiesOfALabelWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->labelPropertiesGet("john.doe@example.com", 1); Arsse::$db->labelPropertiesGet("john.doe@example.com", 1);
} }
public function testMakeNoChangesToALabel():void { public function testMakeNoChangesToALabel(): void {
$this->assertFalse(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, [])); $this->assertFalse(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, []));
} }
public function testRenameALabel():void { public function testRenameALabel(): void {
$this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => "Curious"])); $this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => "Curious"]));
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelPropertiesSet"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelPropertiesSet");
$state = $this->primeExpectations($this->data, $this->checkLabels); $state = $this->primeExpectations($this->data, $this->checkLabels);
@ -398,7 +398,7 @@ trait SeriesLabel {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testRenameALabelByName():void { public function testRenameALabelByName(): void {
$this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", "Interesting", ['name' => "Curious"], true)); $this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", "Interesting", ['name' => "Curious"], true));
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelPropertiesSet"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "labelPropertiesSet");
$state = $this->primeExpectations($this->data, $this->checkLabels); $state = $this->primeExpectations($this->data, $this->checkLabels);
@ -406,53 +406,53 @@ trait SeriesLabel {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testRenameALabelToTheEmptyString():void { public function testRenameALabelToTheEmptyString(): void {
$this->assertException("missing", "Db", "ExceptionInput"); $this->assertException("missing", "Db", "ExceptionInput");
$this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => ""])); $this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => ""]));
} }
public function testRenameALabelToWhitespaceOnly():void { public function testRenameALabelToWhitespaceOnly(): void {
$this->assertException("whitespace", "Db", "ExceptionInput"); $this->assertException("whitespace", "Db", "ExceptionInput");
$this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => " "])); $this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => " "]));
} }
public function testRenameALabelToAnInvalidValue():void { public function testRenameALabelToAnInvalidValue(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
$this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => []])); $this->assertTrue(Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => []]));
} }
public function testCauseALabelCollision():void { public function testCauseALabelCollision(): void {
$this->assertException("constraintViolation", "Db", "ExceptionInput"); $this->assertException("constraintViolation", "Db", "ExceptionInput");
Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => "Fascinating"]); Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => "Fascinating"]);
} }
public function testSetThePropertiesOfAMissingLabel():void { public function testSetThePropertiesOfAMissingLabel(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->labelPropertiesSet("john.doe@example.com", 2112, ['name' => "Exciting"]); Arsse::$db->labelPropertiesSet("john.doe@example.com", 2112, ['name' => "Exciting"]);
} }
public function testSetThePropertiesOfAnInvalidLabel():void { public function testSetThePropertiesOfAnInvalidLabel(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->labelPropertiesSet("john.doe@example.com", -1, ['name' => "Exciting"]); Arsse::$db->labelPropertiesSet("john.doe@example.com", -1, ['name' => "Exciting"]);
} }
public function testSetThePropertiesOfAnInvalidLabelByName():void { public function testSetThePropertiesOfAnInvalidLabelByName(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->labelPropertiesSet("john.doe@example.com", [], ['name' => "Exciting"], true); Arsse::$db->labelPropertiesSet("john.doe@example.com", [], ['name' => "Exciting"], true);
} }
public function testSetThePropertiesOfALabelForTheWrongOwner():void { public function testSetThePropertiesOfALabelForTheWrongOwner(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->labelPropertiesSet("john.doe@example.com", 3, ['name' => "Exciting"]); // label ID 3 belongs to Jane Arsse::$db->labelPropertiesSet("john.doe@example.com", 3, ['name' => "Exciting"]); // label ID 3 belongs to Jane
} }
public function testSetThePropertiesOfALabelWithoutAuthority():void { public function testSetThePropertiesOfALabelWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => "Exciting"]); Arsse::$db->labelPropertiesSet("john.doe@example.com", 1, ['name' => "Exciting"]);
} }
public function testListLabelledArticles():void { public function testListLabelledArticles(): void {
$exp = [1,19]; $exp = [1,19];
$this->assertEquals($exp, Arsse::$db->labelArticlesGet("john.doe@example.com", 1)); $this->assertEquals($exp, Arsse::$db->labelArticlesGet("john.doe@example.com", 1));
$this->assertEquals($exp, Arsse::$db->labelArticlesGet("john.doe@example.com", "Interesting", true)); $this->assertEquals($exp, Arsse::$db->labelArticlesGet("john.doe@example.com", "Interesting", true));
@ -464,23 +464,23 @@ trait SeriesLabel {
$this->assertEquals($exp, Arsse::$db->labelArticlesGet("john.doe@example.com", "Lonely", true)); $this->assertEquals($exp, Arsse::$db->labelArticlesGet("john.doe@example.com", "Lonely", true));
} }
public function testListLabelledArticlesForAMissingLabel():void { public function testListLabelledArticlesForAMissingLabel(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->labelArticlesGet("john.doe@example.com", 3); Arsse::$db->labelArticlesGet("john.doe@example.com", 3);
} }
public function testListLabelledArticlesForAnInvalidLabel():void { public function testListLabelledArticlesForAnInvalidLabel(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->labelArticlesGet("john.doe@example.com", -1); Arsse::$db->labelArticlesGet("john.doe@example.com", -1);
} }
public function testListLabelledArticlesWithoutAuthority():void { public function testListLabelledArticlesWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->labelArticlesGet("john.doe@example.com", 1); Arsse::$db->labelArticlesGet("john.doe@example.com", 1);
} }
public function testApplyALabelToArticles():void { public function testApplyALabelToArticles(): void {
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([2,5])); Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([2,5]));
$state = $this->primeExpectations($this->data, $this->checkMembers); $state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_label_members']['rows'][4][3] = 1; $state['arsse_label_members']['rows'][4][3] = 1;
@ -488,14 +488,14 @@ trait SeriesLabel {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testClearALabelFromArticles():void { public function testClearALabelFromArticles(): void {
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([1,5]), Database::ASSOC_REMOVE); Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([1,5]), Database::ASSOC_REMOVE);
$state = $this->primeExpectations($this->data, $this->checkMembers); $state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_label_members']['rows'][0][3] = 0; $state['arsse_label_members']['rows'][0][3] = 0;
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testApplyALabelToArticlesByName():void { public function testApplyALabelToArticlesByName(): void {
Arsse::$db->labelArticlesSet("john.doe@example.com", "Interesting", (new Context)->articles([2,5]), Database::ASSOC_ADD, true); Arsse::$db->labelArticlesSet("john.doe@example.com", "Interesting", (new Context)->articles([2,5]), Database::ASSOC_ADD, true);
$state = $this->primeExpectations($this->data, $this->checkMembers); $state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_label_members']['rows'][4][3] = 1; $state['arsse_label_members']['rows'][4][3] = 1;
@ -503,26 +503,26 @@ trait SeriesLabel {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testClearALabelFromArticlesByName():void { public function testClearALabelFromArticlesByName(): void {
Arsse::$db->labelArticlesSet("john.doe@example.com", "Interesting", (new Context)->articles([1,5]), Database::ASSOC_REMOVE, true); Arsse::$db->labelArticlesSet("john.doe@example.com", "Interesting", (new Context)->articles([1,5]), Database::ASSOC_REMOVE, true);
$state = $this->primeExpectations($this->data, $this->checkMembers); $state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_label_members']['rows'][0][3] = 0; $state['arsse_label_members']['rows'][0][3] = 0;
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testApplyALabelToNoArticles():void { public function testApplyALabelToNoArticles(): void {
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([10000])); Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([10000]));
$state = $this->primeExpectations($this->data, $this->checkMembers); $state = $this->primeExpectations($this->data, $this->checkMembers);
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testClearALabelFromNoArticles():void { public function testClearALabelFromNoArticles(): void {
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([10000]), Database::ASSOC_REMOVE); Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([10000]), Database::ASSOC_REMOVE);
$state = $this->primeExpectations($this->data, $this->checkMembers); $state = $this->primeExpectations($this->data, $this->checkMembers);
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testReplaceArticlesOfALabel():void { public function testReplaceArticlesOfALabel(): void {
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([2,5]), Database::ASSOC_REPLACE); Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([2,5]), Database::ASSOC_REPLACE);
$state = $this->primeExpectations($this->data, $this->checkMembers); $state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_label_members']['rows'][0][3] = 0; $state['arsse_label_members']['rows'][0][3] = 0;
@ -532,7 +532,7 @@ trait SeriesLabel {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testPurgeArticlesOfALabel():void { public function testPurgeArticlesOfALabel(): void {
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([10000]), Database::ASSOC_REPLACE); Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([10000]), Database::ASSOC_REPLACE);
$state = $this->primeExpectations($this->data, $this->checkMembers); $state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_label_members']['rows'][0][3] = 0; $state['arsse_label_members']['rows'][0][3] = 0;
@ -540,7 +540,7 @@ trait SeriesLabel {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testApplyALabelToArticlesWithoutAuthority():void { public function testApplyALabelToArticlesWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([2,5])); Arsse::$db->labelArticlesSet("john.doe@example.com", 1, (new Context)->articles([2,5]));

14
tests/cases/Database/SeriesMeta.php

@ -10,7 +10,7 @@ use JKingWeb\Arsse\Test\Database;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
trait SeriesMeta { trait SeriesMeta {
protected function setUpSeriesMeta():void { protected function setUpSeriesMeta(): void {
$dataBare = [ $dataBare = [
'arsse_meta' => [ 'arsse_meta' => [
'columns' => [ 'columns' => [
@ -31,18 +31,18 @@ trait SeriesMeta {
$this->primeDatabase(static::$drv, $dataBare); $this->primeDatabase(static::$drv, $dataBare);
} }
protected function tearDownSeriesMeta():void { protected function tearDownSeriesMeta(): void {
unset($this->data); unset($this->data);
} }
public function testAddANewValue():void { public function testAddANewValue(): void {
$this->assertTrue(Arsse::$db->metaSet("favourite", "Cygnus X-1")); $this->assertTrue(Arsse::$db->metaSet("favourite", "Cygnus X-1"));
$state = $this->primeExpectations($this->data, ['arsse_meta' => ['key','value']]); $state = $this->primeExpectations($this->data, ['arsse_meta' => ['key','value']]);
$state['arsse_meta']['rows'][] = ["favourite","Cygnus X-1"]; $state['arsse_meta']['rows'][] = ["favourite","Cygnus X-1"];
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testAddANewTypedValue():void { public function testAddANewTypedValue(): void {
$this->assertTrue(Arsse::$db->metaSet("answer", 42, "int")); $this->assertTrue(Arsse::$db->metaSet("answer", 42, "int"));
$this->assertTrue(Arsse::$db->metaSet("true", true, "bool")); $this->assertTrue(Arsse::$db->metaSet("true", true, "bool"));
$this->assertTrue(Arsse::$db->metaSet("false", false, "bool")); $this->assertTrue(Arsse::$db->metaSet("false", false, "bool"));
@ -55,14 +55,14 @@ trait SeriesMeta {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testChangeAnExistingValue():void { public function testChangeAnExistingValue(): void {
$this->assertTrue(Arsse::$db->metaSet("album", "Hemispheres")); $this->assertTrue(Arsse::$db->metaSet("album", "Hemispheres"));
$state = $this->primeExpectations($this->data, ['arsse_meta' => ['key','value']]); $state = $this->primeExpectations($this->data, ['arsse_meta' => ['key','value']]);
$state['arsse_meta']['rows'][1][1] = "Hemispheres"; $state['arsse_meta']['rows'][1][1] = "Hemispheres";
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testRemoveAValue():void { public function testRemoveAValue(): void {
$this->assertTrue(Arsse::$db->metaRemove("album")); $this->assertTrue(Arsse::$db->metaRemove("album"));
$this->assertFalse(Arsse::$db->metaRemove("album")); $this->assertFalse(Arsse::$db->metaRemove("album"));
$state = $this->primeExpectations($this->data, ['arsse_meta' => ['key','value']]); $state = $this->primeExpectations($this->data, ['arsse_meta' => ['key','value']]);
@ -70,7 +70,7 @@ trait SeriesMeta {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testRetrieveAValue():void { public function testRetrieveAValue(): void {
$this->assertSame("".Database::SCHEMA_VERSION, Arsse::$db->metaGet("schema_version")); $this->assertSame("".Database::SCHEMA_VERSION, Arsse::$db->metaGet("schema_version"));
$this->assertSame("A Farewell to Kings", Arsse::$db->metaGet("album")); $this->assertSame("A Farewell to Kings", Arsse::$db->metaGet("album"));
$this->assertSame(null, Arsse::$db->metaGet("this_key_does_not_exist")); $this->assertSame(null, Arsse::$db->metaGet("this_key_does_not_exist"));

12
tests/cases/Database/SeriesMiscellany.php

@ -10,22 +10,22 @@ use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Database; use JKingWeb\Arsse\Database;
trait SeriesMiscellany { trait SeriesMiscellany {
protected function setUpSeriesMiscellany():void { protected function setUpSeriesMiscellany(): void {
static::setConf([ static::setConf([
'dbDriver' => static::$dbDriverClass, 'dbDriver' => static::$dbDriverClass,
]); ]);
} }
protected function tearDownSeriesMiscellany():void { protected function tearDownSeriesMiscellany(): void {
} }
public function testInitializeDatabase():void { public function testInitializeDatabase(): void {
static::dbRaze(static::$drv); static::dbRaze(static::$drv);
$d = new Database(true); $d = new Database(true);
$this->assertSame(Database::SCHEMA_VERSION, $d->driverSchemaVersion()); $this->assertSame(Database::SCHEMA_VERSION, $d->driverSchemaVersion());
} }
public function testManuallyInitializeDatabase():void { public function testManuallyInitializeDatabase(): void {
static::dbRaze(static::$drv); static::dbRaze(static::$drv);
$d = new Database(false); $d = new Database(false);
$this->assertSame(0, $d->driverSchemaVersion()); $this->assertSame(0, $d->driverSchemaVersion());
@ -34,11 +34,11 @@ trait SeriesMiscellany {
$this->assertFalse($d->driverSchemaUpdate()); $this->assertFalse($d->driverSchemaUpdate());
} }
public function testCheckCharacterSetAcceptability():void { public function testCheckCharacterSetAcceptability(): void {
$this->assertIsBool(Arsse::$db->driverCharsetAcceptable()); $this->assertIsBool(Arsse::$db->driverCharsetAcceptable());
} }
public function testPerformMaintenance():void { public function testPerformMaintenance(): void {
$this->assertTrue(Arsse::$db->driverMaintenance()); $this->assertTrue(Arsse::$db->driverMaintenance());
} }
} }

24
tests/cases/Database/SeriesSession.php

@ -10,7 +10,7 @@ use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Misc\Date; use JKingWeb\Arsse\Misc\Date;
trait SeriesSession { trait SeriesSession {
protected function setUpSeriesSession():void { protected function setUpSeriesSession(): void {
// set up the configuration // set up the configuration
static::setConf([ static::setConf([
'userSessionTimeout' => "PT1H", 'userSessionTimeout' => "PT1H",
@ -49,11 +49,11 @@ trait SeriesSession {
]; ];
} }
protected function tearDownSeriesSession():void { protected function tearDownSeriesSession(): void {
unset($this->data); unset($this->data);
} }
public function testResumeAValidSession():void { public function testResumeAValidSession(): void {
$exp1 = [ $exp1 = [
'id' => "80fa94c1a11f11e78667001e673b2560", 'id' => "80fa94c1a11f11e78667001e673b2560",
'user' => "jane.doe@example.com" 'user' => "jane.doe@example.com"
@ -74,22 +74,22 @@ trait SeriesSession {
$this->assertArraySubset($exp1, Arsse::$db->sessionResume("80fa94c1a11f11e78667001e673b2560")); $this->assertArraySubset($exp1, Arsse::$db->sessionResume("80fa94c1a11f11e78667001e673b2560"));
} }
public function testResumeAMissingSession():void { public function testResumeAMissingSession(): void {
$this->assertException("invalid", "User", "ExceptionSession"); $this->assertException("invalid", "User", "ExceptionSession");
Arsse::$db->sessionResume("thisSessionDoesNotExist"); Arsse::$db->sessionResume("thisSessionDoesNotExist");
} }
public function testResumeAnExpiredSession():void { public function testResumeAnExpiredSession(): void {
$this->assertException("invalid", "User", "ExceptionSession"); $this->assertException("invalid", "User", "ExceptionSession");
Arsse::$db->sessionResume("27c6de8da13311e78667001e673b2560"); Arsse::$db->sessionResume("27c6de8da13311e78667001e673b2560");
} }
public function testResumeAStaleSession():void { public function testResumeAStaleSession(): void {
$this->assertException("invalid", "User", "ExceptionSession"); $this->assertException("invalid", "User", "ExceptionSession");
Arsse::$db->sessionResume("ab3b3eb8a13311e78667001e673b2560"); Arsse::$db->sessionResume("ab3b3eb8a13311e78667001e673b2560");
} }
public function testCreateASession():void { public function testCreateASession(): void {
$user = "jane.doe@example.com"; $user = "jane.doe@example.com";
$id = Arsse::$db->sessionCreate($user); $id = Arsse::$db->sessionCreate($user);
$now = time(); $now = time();
@ -98,13 +98,13 @@ trait SeriesSession {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testCreateASessionWithoutAuthority():void { public function testCreateASessionWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->sessionCreate("jane.doe@example.com"); Arsse::$db->sessionCreate("jane.doe@example.com");
} }
public function testDestroyASession():void { public function testDestroyASession(): void {
$user = "jane.doe@example.com"; $user = "jane.doe@example.com";
$id = "80fa94c1a11f11e78667001e673b2560"; $id = "80fa94c1a11f11e78667001e673b2560";
$this->assertTrue(Arsse::$db->sessionDestroy($user, $id)); $this->assertTrue(Arsse::$db->sessionDestroy($user, $id));
@ -115,7 +115,7 @@ trait SeriesSession {
$this->assertFalse(Arsse::$db->sessionDestroy($user, $id)); $this->assertFalse(Arsse::$db->sessionDestroy($user, $id));
} }
public function testDestroyAllSessions():void { public function testDestroyAllSessions(): void {
$user = "jane.doe@example.com"; $user = "jane.doe@example.com";
$this->assertTrue(Arsse::$db->sessionDestroy($user)); $this->assertTrue(Arsse::$db->sessionDestroy($user));
$state = $this->primeExpectations($this->data, ['arsse_sessions' => ["id", "created", "expires", "user"]]); $state = $this->primeExpectations($this->data, ['arsse_sessions' => ["id", "created", "expires", "user"]]);
@ -125,13 +125,13 @@ trait SeriesSession {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testDestroyASessionForTheWrongUser():void { public function testDestroyASessionForTheWrongUser(): void {
$user = "john.doe@example.com"; $user = "john.doe@example.com";
$id = "80fa94c1a11f11e78667001e673b2560"; $id = "80fa94c1a11f11e78667001e673b2560";
$this->assertFalse(Arsse::$db->sessionDestroy($user, $id)); $this->assertFalse(Arsse::$db->sessionDestroy($user, $id));
} }
public function testDestroyASessionWithoutAuthority():void { public function testDestroyASessionWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->sessionDestroy("jane.doe@example.com", "80fa94c1a11f11e78667001e673b2560"); Arsse::$db->sessionDestroy("jane.doe@example.com", "80fa94c1a11f11e78667001e673b2560");

92
tests/cases/Database/SeriesSubscription.php

@ -11,7 +11,7 @@ use JKingWeb\Arsse\Test\Database;
use JKingWeb\Arsse\Feed\Exception as FeedException; use JKingWeb\Arsse\Feed\Exception as FeedException;
trait SeriesSubscription { trait SeriesSubscription {
public function setUpSeriesSubscription():void { public function setUpSeriesSubscription(): void {
$this->data = [ $this->data = [
'arsse_users' => [ 'arsse_users' => [
'columns' => [ 'columns' => [
@ -143,11 +143,11 @@ trait SeriesSubscription {
$this->user = "john.doe@example.com"; $this->user = "john.doe@example.com";
} }
protected function tearDownSeriesSubscription():void { protected function tearDownSeriesSubscription(): void {
unset($this->data, $this->user); unset($this->data, $this->user);
} }
public function testAddASubscriptionToAnExistingFeed():void { public function testAddASubscriptionToAnExistingFeed(): void {
$url = "http://example.com/feed1"; $url = "http://example.com/feed1";
$subID = $this->nextID("arsse_subscriptions"); $subID = $this->nextID("arsse_subscriptions");
\Phake::when(Arsse::$db)->feedUpdate->thenReturn(true); \Phake::when(Arsse::$db)->feedUpdate->thenReturn(true);
@ -162,7 +162,7 @@ trait SeriesSubscription {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testAddASubscriptionToANewFeed():void { public function testAddASubscriptionToANewFeed(): void {
$url = "http://example.org/feed1"; $url = "http://example.org/feed1";
$feedID = $this->nextID("arsse_feeds"); $feedID = $this->nextID("arsse_feeds");
$subID = $this->nextID("arsse_subscriptions"); $subID = $this->nextID("arsse_subscriptions");
@ -179,7 +179,7 @@ trait SeriesSubscription {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testAddASubscriptionToANewFeedViaDiscovery():void { public function testAddASubscriptionToANewFeedViaDiscovery(): void {
$url = "http://localhost:8000/Feed/Discovery/Valid"; $url = "http://localhost:8000/Feed/Discovery/Valid";
$discovered = "http://localhost:8000/Feed/Discovery/Feed"; $discovered = "http://localhost:8000/Feed/Discovery/Feed";
$feedID = $this->nextID("arsse_feeds"); $feedID = $this->nextID("arsse_feeds");
@ -197,7 +197,7 @@ trait SeriesSubscription {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testAddASubscriptionToAnInvalidFeed():void { public function testAddASubscriptionToAnInvalidFeed(): void {
$url = "http://example.org/feed1"; $url = "http://example.org/feed1";
$feedID = $this->nextID("arsse_feeds"); $feedID = $this->nextID("arsse_feeds");
\Phake::when(Arsse::$db)->feedUpdate->thenThrow(new FeedException($url, new \PicoFeed\Client\InvalidUrlException())); \Phake::when(Arsse::$db)->feedUpdate->thenThrow(new FeedException($url, new \PicoFeed\Client\InvalidUrlException()));
@ -215,19 +215,19 @@ trait SeriesSubscription {
} }
} }
public function testAddADuplicateSubscription():void { public function testAddADuplicateSubscription(): void {
$url = "http://example.com/feed2"; $url = "http://example.com/feed2";
$this->assertException("constraintViolation", "Db", "ExceptionInput"); $this->assertException("constraintViolation", "Db", "ExceptionInput");
Arsse::$db->subscriptionAdd($this->user, $url); Arsse::$db->subscriptionAdd($this->user, $url);
} }
public function testAddADuplicateSubscriptionWithEquivalentUrl():void { public function testAddADuplicateSubscriptionWithEquivalentUrl(): void {
$url = "http://EXAMPLE.COM/feed2"; $url = "http://EXAMPLE.COM/feed2";
$this->assertException("constraintViolation", "Db", "ExceptionInput"); $this->assertException("constraintViolation", "Db", "ExceptionInput");
Arsse::$db->subscriptionAdd($this->user, $url); Arsse::$db->subscriptionAdd($this->user, $url);
} }
public function testAddADuplicateSubscriptionViaRedirection():void { public function testAddADuplicateSubscriptionViaRedirection(): void {
$url = "http://localhost:8000/Feed/Parsing/Valid"; $url = "http://localhost:8000/Feed/Parsing/Valid";
Arsse::$db->subscriptionAdd($this->user, $url); Arsse::$db->subscriptionAdd($this->user, $url);
$subID = $this->nextID("arsse_subscriptions"); $subID = $this->nextID("arsse_subscriptions");
@ -235,14 +235,14 @@ trait SeriesSubscription {
$this->assertSame($subID, Arsse::$db->subscriptionAdd($this->user, $url)); $this->assertSame($subID, Arsse::$db->subscriptionAdd($this->user, $url));
} }
public function testAddASubscriptionWithoutAuthority():void { public function testAddASubscriptionWithoutAuthority(): void {
$url = "http://example.com/feed1"; $url = "http://example.com/feed1";
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->subscriptionAdd($this->user, $url); Arsse::$db->subscriptionAdd($this->user, $url);
} }
public function testRemoveASubscription():void { public function testRemoveASubscription(): void {
$this->assertTrue(Arsse::$db->subscriptionRemove($this->user, 1)); $this->assertTrue(Arsse::$db->subscriptionRemove($this->user, 1));
\Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionRemove"); \Phake::verify(Arsse::$user)->authorize($this->user, "subscriptionRemove");
$state = $this->primeExpectations($this->data, [ $state = $this->primeExpectations($this->data, [
@ -253,29 +253,29 @@ trait SeriesSubscription {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testRemoveAMissingSubscription():void { public function testRemoveAMissingSubscription(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->subscriptionRemove($this->user, 2112); Arsse::$db->subscriptionRemove($this->user, 2112);
} }
public function testRemoveAnInvalidSubscription():void { public function testRemoveAnInvalidSubscription(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->subscriptionRemove($this->user, -1); Arsse::$db->subscriptionRemove($this->user, -1);
} }
public function testRemoveASubscriptionForTheWrongOwner():void { public function testRemoveASubscriptionForTheWrongOwner(): void {
$this->user = "jane.doe@example.com"; $this->user = "jane.doe@example.com";
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->subscriptionRemove($this->user, 1); Arsse::$db->subscriptionRemove($this->user, 1);
} }
public function testRemoveASubscriptionWithoutAuthority():void { public function testRemoveASubscriptionWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->subscriptionRemove($this->user, 1); Arsse::$db->subscriptionRemove($this->user, 1);
} }
public function testListSubscriptions():void { public function testListSubscriptions(): void {
$exp = [ $exp = [
[ [
'url' => "http://example.com/feed2", 'url' => "http://example.com/feed2",
@ -303,7 +303,7 @@ trait SeriesSubscription {
$this->assertArraySubset($exp[1], Arsse::$db->subscriptionPropertiesGet($this->user, 3)); $this->assertArraySubset($exp[1], Arsse::$db->subscriptionPropertiesGet($this->user, 3));
} }
public function testListSubscriptionsInAFolder():void { public function testListSubscriptionsInAFolder(): void {
$exp = [ $exp = [
[ [
'url' => "http://example.com/feed2", 'url' => "http://example.com/feed2",
@ -318,7 +318,7 @@ trait SeriesSubscription {
$this->assertResult($exp, Arsse::$db->subscriptionList($this->user, null, false)); $this->assertResult($exp, Arsse::$db->subscriptionList($this->user, null, false));
} }
public function testListSubscriptionsWithoutRecursion():void { public function testListSubscriptionsWithoutRecursion(): void {
$exp = [ $exp = [
[ [
'url' => "http://example.com/feed3", 'url' => "http://example.com/feed3",
@ -333,50 +333,50 @@ trait SeriesSubscription {
$this->assertResult($exp, Arsse::$db->subscriptionList($this->user, 2)); $this->assertResult($exp, Arsse::$db->subscriptionList($this->user, 2));
} }
public function testListSubscriptionsInAMissingFolder():void { public function testListSubscriptionsInAMissingFolder(): void {
$this->assertException("idMissing", "Db", "ExceptionInput"); $this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->subscriptionList($this->user, 4); Arsse::$db->subscriptionList($this->user, 4);
} }
public function testListSubscriptionsWithoutAuthority():void { public function testListSubscriptionsWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->subscriptionList($this->user); Arsse::$db->subscriptionList($this->user);
} }
public function testCountSubscriptions():void { public function testCountSubscriptions(): void {
$this->assertSame(2, Arsse::$db->subscriptionCount($this->user)); $this->assertSame(2, Arsse::$db->subscriptionCount($this->user));
$this->assertSame(1, Arsse::$db->subscriptionCount($this->user, 2)); $this->assertSame(1, Arsse::$db->subscriptionCount($this->user, 2));
} }
public function testCountSubscriptionsInAMissingFolder():void { public function testCountSubscriptionsInAMissingFolder(): void {
$this->assertException("idMissing", "Db", "ExceptionInput"); $this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->subscriptionCount($this->user, 4); Arsse::$db->subscriptionCount($this->user, 4);
} }
public function testCountSubscriptionsWithoutAuthority():void { public function testCountSubscriptionsWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->subscriptionCount($this->user); Arsse::$db->subscriptionCount($this->user);
} }
public function testGetThePropertiesOfAMissingSubscription():void { public function testGetThePropertiesOfAMissingSubscription(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->subscriptionPropertiesGet($this->user, 2112); Arsse::$db->subscriptionPropertiesGet($this->user, 2112);
} }
public function testGetThePropertiesOfAnInvalidSubscription():void { public function testGetThePropertiesOfAnInvalidSubscription(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->subscriptionPropertiesGet($this->user, -1); Arsse::$db->subscriptionPropertiesGet($this->user, -1);
} }
public function testGetThePropertiesOfASubscriptionWithoutAuthority():void { public function testGetThePropertiesOfASubscriptionWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->subscriptionPropertiesGet($this->user, 1); Arsse::$db->subscriptionPropertiesGet($this->user, 1);
} }
public function testSetThePropertiesOfASubscription():void { public function testSetThePropertiesOfASubscription(): void {
Arsse::$db->subscriptionPropertiesSet($this->user, 1, [ Arsse::$db->subscriptionPropertiesSet($this->user, 1, [
'title' => "Ook Ook", 'title' => "Ook Ook",
'folder' => 3, 'folder' => 3,
@ -400,56 +400,56 @@ trait SeriesSubscription {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testMoveASubscriptionToAMissingFolder():void { public function testMoveASubscriptionToAMissingFolder(): void {
$this->assertException("idMissing", "Db", "ExceptionInput"); $this->assertException("idMissing", "Db", "ExceptionInput");
Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['folder' => 4]); Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['folder' => 4]);
} }
public function testMoveASubscriptionToTheRootFolder():void { public function testMoveASubscriptionToTheRootFolder(): void {
$this->assertTrue(Arsse::$db->subscriptionPropertiesSet($this->user, 3, ['folder' => null])); $this->assertTrue(Arsse::$db->subscriptionPropertiesSet($this->user, 3, ['folder' => null]));
} }
public function testRenameASubscriptionToABlankTitle():void { public function testRenameASubscriptionToABlankTitle(): void {
$this->assertException("missing", "Db", "ExceptionInput"); $this->assertException("missing", "Db", "ExceptionInput");
Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['title' => ""]); Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['title' => ""]);
} }
public function testRenameASubscriptionToAWhitespaceTitle():void { public function testRenameASubscriptionToAWhitespaceTitle(): void {
$this->assertException("whitespace", "Db", "ExceptionInput"); $this->assertException("whitespace", "Db", "ExceptionInput");
Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['title' => " "]); Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['title' => " "]);
} }
public function testRenameASubscriptionToFalse():void { public function testRenameASubscriptionToFalse(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['title' => false]); Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['title' => false]);
} }
public function testRenameASubscriptionToZero():void { public function testRenameASubscriptionToZero(): void {
$this->assertTrue(Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['title' => 0])); $this->assertTrue(Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['title' => 0]));
} }
public function testRenameASubscriptionToAnArray():void { public function testRenameASubscriptionToAnArray(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['title' => []]); Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['title' => []]);
} }
public function testSetThePropertiesOfAMissingSubscription():void { public function testSetThePropertiesOfAMissingSubscription(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->subscriptionPropertiesSet($this->user, 2112, ['folder' => null]); Arsse::$db->subscriptionPropertiesSet($this->user, 2112, ['folder' => null]);
} }
public function testSetThePropertiesOfAnInvalidSubscription():void { public function testSetThePropertiesOfAnInvalidSubscription(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->subscriptionPropertiesSet($this->user, -1, ['folder' => null]); Arsse::$db->subscriptionPropertiesSet($this->user, -1, ['folder' => null]);
} }
public function testSetThePropertiesOfASubscriptionWithoutAuthority():void { public function testSetThePropertiesOfASubscriptionWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['folder' => null]); Arsse::$db->subscriptionPropertiesSet($this->user, 1, ['folder' => null]);
} }
public function testRetrieveTheFaviconOfASubscription():void { public function testRetrieveTheFaviconOfASubscription(): void {
$exp = "http://example.com/favicon.ico"; $exp = "http://example.com/favicon.ico";
$this->assertSame($exp, Arsse::$db->subscriptionFavicon(1)); $this->assertSame($exp, Arsse::$db->subscriptionFavicon(1));
$this->assertSame($exp, Arsse::$db->subscriptionFavicon(2)); $this->assertSame($exp, Arsse::$db->subscriptionFavicon(2));
@ -465,7 +465,7 @@ trait SeriesSubscription {
$this->assertSame('', Arsse::$db->subscriptionFavicon(-2112)); $this->assertSame('', Arsse::$db->subscriptionFavicon(-2112));
} }
public function testRetrieveTheFaviconOfASubscriptionWithUser():void { public function testRetrieveTheFaviconOfASubscriptionWithUser(): void {
$exp = "http://example.com/favicon.ico"; $exp = "http://example.com/favicon.ico";
$user = "john.doe@example.com"; $user = "john.doe@example.com";
$this->assertSame($exp, Arsse::$db->subscriptionFavicon(1, $user)); $this->assertSame($exp, Arsse::$db->subscriptionFavicon(1, $user));
@ -479,7 +479,7 @@ trait SeriesSubscription {
$this->assertSame('', Arsse::$db->subscriptionFavicon(4, $user)); $this->assertSame('', Arsse::$db->subscriptionFavicon(4, $user));
} }
public function testRetrieveTheFaviconOfASubscriptionWithUserWithoutAuthority():void { public function testRetrieveTheFaviconOfASubscriptionWithUserWithoutAuthority(): void {
$exp = "http://example.com/favicon.ico"; $exp = "http://example.com/favicon.ico";
$user = "john.doe@example.com"; $user = "john.doe@example.com";
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
@ -487,36 +487,36 @@ trait SeriesSubscription {
Arsse::$db->subscriptionFavicon(-2112, $user); Arsse::$db->subscriptionFavicon(-2112, $user);
} }
public function testListTheTagsOfASubscription():void { public function testListTheTagsOfASubscription(): void {
$this->assertEquals([1,2], Arsse::$db->subscriptionTagsGet("john.doe@example.com", 1)); $this->assertEquals([1,2], Arsse::$db->subscriptionTagsGet("john.doe@example.com", 1));
$this->assertEquals([2], Arsse::$db->subscriptionTagsGet("john.doe@example.com", 3)); $this->assertEquals([2], Arsse::$db->subscriptionTagsGet("john.doe@example.com", 3));
$this->assertEquals(["Fascinating","Interesting"], Arsse::$db->subscriptionTagsGet("john.doe@example.com", 1, true)); $this->assertEquals(["Fascinating","Interesting"], Arsse::$db->subscriptionTagsGet("john.doe@example.com", 1, true));
$this->assertEquals(["Fascinating"], Arsse::$db->subscriptionTagsGet("john.doe@example.com", 3, true)); $this->assertEquals(["Fascinating"], Arsse::$db->subscriptionTagsGet("john.doe@example.com", 3, true));
} }
public function testListTheTagsOfAMissingSubscription():void { public function testListTheTagsOfAMissingSubscription(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->subscriptionTagsGet($this->user, 101); Arsse::$db->subscriptionTagsGet($this->user, 101);
} }
public function testListTheTagsOfASubscriptionWithoutAuthority():void { public function testListTheTagsOfASubscriptionWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->subscriptionTagsGet("john.doe@example.com", 1); Arsse::$db->subscriptionTagsGet("john.doe@example.com", 1);
} }
public function testGetRefreshTimeOfASubscription():void { public function testGetRefreshTimeOfASubscription(): void {
$user = "john.doe@example.com"; $user = "john.doe@example.com";
$this->assertTime(strtotime("now + 1 hour"), Arsse::$db->subscriptionRefreshed($user)); $this->assertTime(strtotime("now + 1 hour"), Arsse::$db->subscriptionRefreshed($user));
$this->assertTime(strtotime("now - 1 hour"), Arsse::$db->subscriptionRefreshed($user, 1)); $this->assertTime(strtotime("now - 1 hour"), Arsse::$db->subscriptionRefreshed($user, 1));
} }
public function testGetRefreshTimeOfAMissingSubscription():void { public function testGetRefreshTimeOfAMissingSubscription(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
$this->assertTime(strtotime("now - 1 hour"), Arsse::$db->subscriptionRefreshed("john.doe@example.com", 2)); $this->assertTime(strtotime("now - 1 hour"), Arsse::$db->subscriptionRefreshed("john.doe@example.com", 2));
} }
public function testGetRefreshTimeOfASubscriptionWithoutAuthority():void { public function testGetRefreshTimeOfASubscriptionWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
$this->assertTime(strtotime("now + 1 hour"), Arsse::$db->subscriptionRefreshed("john.doe@example.com")); $this->assertTime(strtotime("now + 1 hour"), Arsse::$db->subscriptionRefreshed("john.doe@example.com"));

100
tests/cases/Database/SeriesTag.php

@ -10,7 +10,7 @@ use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Database; use JKingWeb\Arsse\Database;
trait SeriesTag { trait SeriesTag {
protected function setUpSeriesTag():void { protected function setUpSeriesTag(): void {
$this->data = [ $this->data = [
'arsse_users' => [ 'arsse_users' => [
'columns' => [ 'columns' => [
@ -104,11 +104,11 @@ trait SeriesTag {
$this->user = "john.doe@example.com"; $this->user = "john.doe@example.com";
} }
protected function tearDownSeriesTag():void { protected function tearDownSeriesTag(): void {
unset($this->data, $this->checkTags, $this->checkMembers, $this->user); unset($this->data, $this->checkTags, $this->checkMembers, $this->user);
} }
public function testAddATag():void { public function testAddATag(): void {
$user = "john.doe@example.com"; $user = "john.doe@example.com";
$tagID = $this->nextID("arsse_tags"); $tagID = $this->nextID("arsse_tags");
$this->assertSame($tagID, Arsse::$db->tagAdd($user, ['name' => "Entertaining"])); $this->assertSame($tagID, Arsse::$db->tagAdd($user, ['name' => "Entertaining"]));
@ -118,33 +118,33 @@ trait SeriesTag {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testAddADuplicateTag():void { public function testAddADuplicateTag(): void {
$this->assertException("constraintViolation", "Db", "ExceptionInput"); $this->assertException("constraintViolation", "Db", "ExceptionInput");
Arsse::$db->tagAdd("john.doe@example.com", ['name' => "Interesting"]); Arsse::$db->tagAdd("john.doe@example.com", ['name' => "Interesting"]);
} }
public function testAddATagWithAMissingName():void { public function testAddATagWithAMissingName(): void {
$this->assertException("missing", "Db", "ExceptionInput"); $this->assertException("missing", "Db", "ExceptionInput");
Arsse::$db->tagAdd("john.doe@example.com", []); Arsse::$db->tagAdd("john.doe@example.com", []);
} }
public function testAddATagWithABlankName():void { public function testAddATagWithABlankName(): void {
$this->assertException("missing", "Db", "ExceptionInput"); $this->assertException("missing", "Db", "ExceptionInput");
Arsse::$db->tagAdd("john.doe@example.com", ['name' => ""]); Arsse::$db->tagAdd("john.doe@example.com", ['name' => ""]);
} }
public function testAddATagWithAWhitespaceName():void { public function testAddATagWithAWhitespaceName(): void {
$this->assertException("whitespace", "Db", "ExceptionInput"); $this->assertException("whitespace", "Db", "ExceptionInput");
Arsse::$db->tagAdd("john.doe@example.com", ['name' => " "]); Arsse::$db->tagAdd("john.doe@example.com", ['name' => " "]);
} }
public function testAddATagWithoutAuthority():void { public function testAddATagWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tagAdd("john.doe@example.com", ['name' => "Boring"]); Arsse::$db->tagAdd("john.doe@example.com", ['name' => "Boring"]);
} }
public function testListTags():void { public function testListTags(): void {
$exp = [ $exp = [
['id' => 2, 'name' => "Fascinating"], ['id' => 2, 'name' => "Fascinating"],
['id' => 1, 'name' => "Interesting"], ['id' => 1, 'name' => "Interesting"],
@ -160,13 +160,13 @@ trait SeriesTag {
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagList"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagList");
} }
public function testListTagsWithoutAuthority():void { public function testListTagsWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tagList("john.doe@example.com"); Arsse::$db->tagList("john.doe@example.com");
} }
public function testRemoveATag():void { public function testRemoveATag(): void {
$this->assertTrue(Arsse::$db->tagRemove("john.doe@example.com", 1)); $this->assertTrue(Arsse::$db->tagRemove("john.doe@example.com", 1));
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagRemove"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagRemove");
$state = $this->primeExpectations($this->data, $this->checkTags); $state = $this->primeExpectations($this->data, $this->checkTags);
@ -174,7 +174,7 @@ trait SeriesTag {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testRemoveATagByName():void { public function testRemoveATagByName(): void {
$this->assertTrue(Arsse::$db->tagRemove("john.doe@example.com", "Interesting", true)); $this->assertTrue(Arsse::$db->tagRemove("john.doe@example.com", "Interesting", true));
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagRemove"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagRemove");
$state = $this->primeExpectations($this->data, $this->checkTags); $state = $this->primeExpectations($this->data, $this->checkTags);
@ -182,33 +182,33 @@ trait SeriesTag {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testRemoveAMissingTag():void { public function testRemoveAMissingTag(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tagRemove("john.doe@example.com", 2112); Arsse::$db->tagRemove("john.doe@example.com", 2112);
} }
public function testRemoveAnInvalidTag():void { public function testRemoveAnInvalidTag(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->tagRemove("john.doe@example.com", -1); Arsse::$db->tagRemove("john.doe@example.com", -1);
} }
public function testRemoveAnInvalidTagByName():void { public function testRemoveAnInvalidTagByName(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->tagRemove("john.doe@example.com", [], true); Arsse::$db->tagRemove("john.doe@example.com", [], true);
} }
public function testRemoveATagOfTheWrongOwner():void { public function testRemoveATagOfTheWrongOwner(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tagRemove("john.doe@example.com", 3); // tag ID 3 belongs to Jane Arsse::$db->tagRemove("john.doe@example.com", 3); // tag ID 3 belongs to Jane
} }
public function testRemoveATagWithoutAuthority():void { public function testRemoveATagWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tagRemove("john.doe@example.com", 1); Arsse::$db->tagRemove("john.doe@example.com", 1);
} }
public function testGetThePropertiesOfATag():void { public function testGetThePropertiesOfATag(): void {
$exp = [ $exp = [
'id' => 2, 'id' => 2,
'name' => "Fascinating", 'name' => "Fascinating",
@ -218,37 +218,37 @@ trait SeriesTag {
\Phake::verify(Arsse::$user, \Phake::times(2))->authorize("john.doe@example.com", "tagPropertiesGet"); \Phake::verify(Arsse::$user, \Phake::times(2))->authorize("john.doe@example.com", "tagPropertiesGet");
} }
public function testGetThePropertiesOfAMissingTag():void { public function testGetThePropertiesOfAMissingTag(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesGet("john.doe@example.com", 2112); Arsse::$db->tagPropertiesGet("john.doe@example.com", 2112);
} }
public function testGetThePropertiesOfAnInvalidTag():void { public function testGetThePropertiesOfAnInvalidTag(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesGet("john.doe@example.com", -1); Arsse::$db->tagPropertiesGet("john.doe@example.com", -1);
} }
public function testGetThePropertiesOfAnInvalidTagByName():void { public function testGetThePropertiesOfAnInvalidTagByName(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesGet("john.doe@example.com", [], true); Arsse::$db->tagPropertiesGet("john.doe@example.com", [], true);
} }
public function testGetThePropertiesOfATagOfTheWrongOwner():void { public function testGetThePropertiesOfATagOfTheWrongOwner(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesGet("john.doe@example.com", 3); // tag ID 3 belongs to Jane Arsse::$db->tagPropertiesGet("john.doe@example.com", 3); // tag ID 3 belongs to Jane
} }
public function testGetThePropertiesOfATagWithoutAuthority():void { public function testGetThePropertiesOfATagWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tagPropertiesGet("john.doe@example.com", 1); Arsse::$db->tagPropertiesGet("john.doe@example.com", 1);
} }
public function testMakeNoChangesToATag():void { public function testMakeNoChangesToATag(): void {
$this->assertFalse(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, [])); $this->assertFalse(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, []));
} }
public function testRenameATag():void { public function testRenameATag(): void {
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => "Curious"])); $this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => "Curious"]));
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagPropertiesSet"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagPropertiesSet");
$state = $this->primeExpectations($this->data, $this->checkTags); $state = $this->primeExpectations($this->data, $this->checkTags);
@ -256,7 +256,7 @@ trait SeriesTag {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testRenameATagByName():void { public function testRenameATagByName(): void {
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", "Interesting", ['name' => "Curious"], true)); $this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", "Interesting", ['name' => "Curious"], true));
\Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagPropertiesSet"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.com", "tagPropertiesSet");
$state = $this->primeExpectations($this->data, $this->checkTags); $state = $this->primeExpectations($this->data, $this->checkTags);
@ -264,53 +264,53 @@ trait SeriesTag {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testRenameATagToTheEmptyString():void { public function testRenameATagToTheEmptyString(): void {
$this->assertException("missing", "Db", "ExceptionInput"); $this->assertException("missing", "Db", "ExceptionInput");
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => ""])); $this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => ""]));
} }
public function testRenameATagToWhitespaceOnly():void { public function testRenameATagToWhitespaceOnly(): void {
$this->assertException("whitespace", "Db", "ExceptionInput"); $this->assertException("whitespace", "Db", "ExceptionInput");
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => " "])); $this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => " "]));
} }
public function testRenameATagToAnInvalidValue():void { public function testRenameATagToAnInvalidValue(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
$this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => []])); $this->assertTrue(Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => []]));
} }
public function testCauseATagCollision():void { public function testCauseATagCollision(): void {
$this->assertException("constraintViolation", "Db", "ExceptionInput"); $this->assertException("constraintViolation", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => "Fascinating"]); Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => "Fascinating"]);
} }
public function testSetThePropertiesOfAMissingTag():void { public function testSetThePropertiesOfAMissingTag(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesSet("john.doe@example.com", 2112, ['name' => "Exciting"]); Arsse::$db->tagPropertiesSet("john.doe@example.com", 2112, ['name' => "Exciting"]);
} }
public function testSetThePropertiesOfAnInvalidTag():void { public function testSetThePropertiesOfAnInvalidTag(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesSet("john.doe@example.com", -1, ['name' => "Exciting"]); Arsse::$db->tagPropertiesSet("john.doe@example.com", -1, ['name' => "Exciting"]);
} }
public function testSetThePropertiesOfAnInvalidTagByName():void { public function testSetThePropertiesOfAnInvalidTagByName(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesSet("john.doe@example.com", [], ['name' => "Exciting"], true); Arsse::$db->tagPropertiesSet("john.doe@example.com", [], ['name' => "Exciting"], true);
} }
public function testSetThePropertiesOfATagForTheWrongOwner():void { public function testSetThePropertiesOfATagForTheWrongOwner(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tagPropertiesSet("john.doe@example.com", 3, ['name' => "Exciting"]); // tag ID 3 belongs to Jane Arsse::$db->tagPropertiesSet("john.doe@example.com", 3, ['name' => "Exciting"]); // tag ID 3 belongs to Jane
} }
public function testSetThePropertiesOfATagWithoutAuthority():void { public function testSetThePropertiesOfATagWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => "Exciting"]); Arsse::$db->tagPropertiesSet("john.doe@example.com", 1, ['name' => "Exciting"]);
} }
public function testListTaggedSubscriptions():void { public function testListTaggedSubscriptions(): void {
$exp = [1,5]; $exp = [1,5];
$this->assertEquals($exp, Arsse::$db->tagSubscriptionsGet("john.doe@example.com", 1)); $this->assertEquals($exp, Arsse::$db->tagSubscriptionsGet("john.doe@example.com", 1));
$this->assertEquals($exp, Arsse::$db->tagSubscriptionsGet("john.doe@example.com", "Interesting", true)); $this->assertEquals($exp, Arsse::$db->tagSubscriptionsGet("john.doe@example.com", "Interesting", true));
@ -322,23 +322,23 @@ trait SeriesTag {
$this->assertEquals($exp, Arsse::$db->tagSubscriptionsGet("john.doe@example.com", "Lonely", true)); $this->assertEquals($exp, Arsse::$db->tagSubscriptionsGet("john.doe@example.com", "Lonely", true));
} }
public function testListTaggedSubscriptionsForAMissingTag():void { public function testListTaggedSubscriptionsForAMissingTag(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tagSubscriptionsGet("john.doe@example.com", 3); Arsse::$db->tagSubscriptionsGet("john.doe@example.com", 3);
} }
public function testListTaggedSubscriptionsForAnInvalidTag():void { public function testListTaggedSubscriptionsForAnInvalidTag(): void {
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
Arsse::$db->tagSubscriptionsGet("john.doe@example.com", -1); Arsse::$db->tagSubscriptionsGet("john.doe@example.com", -1);
} }
public function testListTaggedSubscriptionsWithoutAuthority():void { public function testListTaggedSubscriptionsWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tagSubscriptionsGet("john.doe@example.com", 1); Arsse::$db->tagSubscriptionsGet("john.doe@example.com", 1);
} }
public function testApplyATagToSubscriptions():void { public function testApplyATagToSubscriptions(): void {
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [3,4]); Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [3,4]);
$state = $this->primeExpectations($this->data, $this->checkMembers); $state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_tag_members']['rows'][1][2] = 1; $state['arsse_tag_members']['rows'][1][2] = 1;
@ -346,14 +346,14 @@ trait SeriesTag {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testClearATagFromSubscriptions():void { public function testClearATagFromSubscriptions(): void {
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [1,3], Database::ASSOC_REMOVE); Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [1,3], Database::ASSOC_REMOVE);
$state = $this->primeExpectations($this->data, $this->checkMembers); $state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_tag_members']['rows'][0][2] = 0; $state['arsse_tag_members']['rows'][0][2] = 0;
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testApplyATagToSubscriptionsByName():void { public function testApplyATagToSubscriptionsByName(): void {
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [3,4], Database::ASSOC_ADD, true); Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [3,4], Database::ASSOC_ADD, true);
$state = $this->primeExpectations($this->data, $this->checkMembers); $state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_tag_members']['rows'][1][2] = 1; $state['arsse_tag_members']['rows'][1][2] = 1;
@ -361,26 +361,26 @@ trait SeriesTag {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testClearATagFromSubscriptionsByName():void { public function testClearATagFromSubscriptionsByName(): void {
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [1,3], Database::ASSOC_REMOVE, true); Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [1,3], Database::ASSOC_REMOVE, true);
$state = $this->primeExpectations($this->data, $this->checkMembers); $state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_tag_members']['rows'][0][2] = 0; $state['arsse_tag_members']['rows'][0][2] = 0;
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testApplyATagToNoSubscriptionsByName():void { public function testApplyATagToNoSubscriptionsByName(): void {
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [], Database::ASSOC_ADD, true); Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [], Database::ASSOC_ADD, true);
$state = $this->primeExpectations($this->data, $this->checkMembers); $state = $this->primeExpectations($this->data, $this->checkMembers);
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testClearATagFromNoSubscriptionsByName():void { public function testClearATagFromNoSubscriptionsByName(): void {
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [], Database::ASSOC_REMOVE, true); Arsse::$db->tagSubscriptionsSet("john.doe@example.com", "Interesting", [], Database::ASSOC_REMOVE, true);
$state = $this->primeExpectations($this->data, $this->checkMembers); $state = $this->primeExpectations($this->data, $this->checkMembers);
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testReplaceSubscriptionsOfATag():void { public function testReplaceSubscriptionsOfATag(): void {
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [3,4], Database::ASSOC_REPLACE); Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [3,4], Database::ASSOC_REPLACE);
$state = $this->primeExpectations($this->data, $this->checkMembers); $state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_tag_members']['rows'][0][2] = 0; $state['arsse_tag_members']['rows'][0][2] = 0;
@ -390,7 +390,7 @@ trait SeriesTag {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testPurgeSubscriptionsOfATag():void { public function testPurgeSubscriptionsOfATag(): void {
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [], Database::ASSOC_REPLACE); Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [], Database::ASSOC_REPLACE);
$state = $this->primeExpectations($this->data, $this->checkMembers); $state = $this->primeExpectations($this->data, $this->checkMembers);
$state['arsse_tag_members']['rows'][0][2] = 0; $state['arsse_tag_members']['rows'][0][2] = 0;
@ -398,13 +398,13 @@ trait SeriesTag {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testApplyATagToSubscriptionsWithoutAuthority():void { public function testApplyATagToSubscriptionsWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [3,4]); Arsse::$db->tagSubscriptionsSet("john.doe@example.com", 1, [3,4]);
} }
public function testSummarizeTags():void { public function testSummarizeTags(): void {
$exp = [ $exp = [
['id' => 1, 'name' => "Interesting", 'subscription' => 1], ['id' => 1, 'name' => "Interesting", 'subscription' => 1],
['id' => 1, 'name' => "Interesting", 'subscription' => 5], ['id' => 1, 'name' => "Interesting", 'subscription' => 5],
@ -415,7 +415,7 @@ trait SeriesTag {
$this->assertResult($exp, Arsse::$db->tagSummarize("john.doe@example.com")); $this->assertResult($exp, Arsse::$db->tagSummarize("john.doe@example.com"));
} }
public function testSummarizeTagsWithoutAuthority():void { public function testSummarizeTagsWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tagSummarize("john.doe@example.com"); Arsse::$db->tagSummarize("john.doe@example.com");

24
tests/cases/Database/SeriesToken.php

@ -9,7 +9,7 @@ namespace JKingWeb\Arsse\TestCase\Database;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
trait SeriesToken { trait SeriesToken {
protected function setUpSeriesToken():void { protected function setUpSeriesToken(): void {
// set up the test data // set up the test data
$past = gmdate("Y-m-d H:i:s", strtotime("now - 1 minute")); $past = gmdate("Y-m-d H:i:s", strtotime("now - 1 minute"));
$future = gmdate("Y-m-d H:i:s", strtotime("now + 1 minute")); $future = gmdate("Y-m-d H:i:s", strtotime("now + 1 minute"));
@ -43,11 +43,11 @@ trait SeriesToken {
]; ];
} }
protected function tearDownSeriesToken():void { protected function tearDownSeriesToken(): void {
unset($this->data); unset($this->data);
} }
public function testLookUpAValidToken():void { public function testLookUpAValidToken(): void {
$exp1 = [ $exp1 = [
'id' => "80fa94c1a11f11e78667001e673b2560", 'id' => "80fa94c1a11f11e78667001e673b2560",
'class' => "fever.login", 'class' => "fever.login",
@ -71,22 +71,22 @@ trait SeriesToken {
$this->assertArraySubset($exp1, Arsse::$db->tokenLookup("fever.login", "80fa94c1a11f11e78667001e673b2560")); $this->assertArraySubset($exp1, Arsse::$db->tokenLookup("fever.login", "80fa94c1a11f11e78667001e673b2560"));
} }
public function testLookUpAMissingToken():void { public function testLookUpAMissingToken(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tokenLookup("class", "thisTokenDoesNotExist"); Arsse::$db->tokenLookup("class", "thisTokenDoesNotExist");
} }
public function testLookUpAnExpiredToken():void { public function testLookUpAnExpiredToken(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tokenLookup("fever.login", "27c6de8da13311e78667001e673b2560"); Arsse::$db->tokenLookup("fever.login", "27c6de8da13311e78667001e673b2560");
} }
public function testLookUpATokenOfTheWrongClass():void { public function testLookUpATokenOfTheWrongClass(): void {
$this->assertException("subjectMissing", "Db", "ExceptionInput"); $this->assertException("subjectMissing", "Db", "ExceptionInput");
Arsse::$db->tokenLookup("some.class", "80fa94c1a11f11e78667001e673b2560"); Arsse::$db->tokenLookup("some.class", "80fa94c1a11f11e78667001e673b2560");
} }
public function testCreateAToken():void { public function testCreateAToken(): void {
$user = "jane.doe@example.com"; $user = "jane.doe@example.com";
$state = $this->primeExpectations($this->data, ['arsse_tokens' => ["id", "class", "expires", "user"]]); $state = $this->primeExpectations($this->data, ['arsse_tokens' => ["id", "class", "expires", "user"]]);
$id = Arsse::$db->tokenCreate($user, "fever.login"); $id = Arsse::$db->tokenCreate($user, "fever.login");
@ -100,18 +100,18 @@ trait SeriesToken {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testCreateATokenForAMissingUser():void { public function testCreateATokenForAMissingUser(): void {
$this->assertException("doesNotExist", "User"); $this->assertException("doesNotExist", "User");
Arsse::$db->tokenCreate("fever.login", "jane.doe@example.biz"); Arsse::$db->tokenCreate("fever.login", "jane.doe@example.biz");
} }
public function testCreateATokenWithoutAuthority():void { public function testCreateATokenWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tokenCreate("fever.login", "jane.doe@example.com"); Arsse::$db->tokenCreate("fever.login", "jane.doe@example.com");
} }
public function testRevokeAToken():void { public function testRevokeAToken(): void {
$user = "jane.doe@example.com"; $user = "jane.doe@example.com";
$id = "80fa94c1a11f11e78667001e673b2560"; $id = "80fa94c1a11f11e78667001e673b2560";
$this->assertTrue(Arsse::$db->tokenRevoke($user, "fever.login", $id)); $this->assertTrue(Arsse::$db->tokenRevoke($user, "fever.login", $id));
@ -122,7 +122,7 @@ trait SeriesToken {
$this->assertFalse(Arsse::$db->tokenRevoke($user, "fever.login", $id)); $this->assertFalse(Arsse::$db->tokenRevoke($user, "fever.login", $id));
} }
public function testRevokeAllTokens():void { public function testRevokeAllTokens(): void {
$user = "jane.doe@example.com"; $user = "jane.doe@example.com";
$state = $this->primeExpectations($this->data, ['arsse_tokens' => ["id", "expires", "user"]]); $state = $this->primeExpectations($this->data, ['arsse_tokens' => ["id", "expires", "user"]]);
$this->assertTrue(Arsse::$db->tokenRevoke($user, "fever.login")); $this->assertTrue(Arsse::$db->tokenRevoke($user, "fever.login"));
@ -136,7 +136,7 @@ trait SeriesToken {
$this->assertFalse(Arsse::$db->tokenRevoke($user, "unknown.class")); $this->assertFalse(Arsse::$db->tokenRevoke($user, "unknown.class"));
} }
public function testRevokeATokenWithoutAuthority():void { public function testRevokeATokenWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->tokenRevoke("jane.doe@example.com", "fever.login"); Arsse::$db->tokenRevoke("jane.doe@example.com", "fever.login");

38
tests/cases/Database/SeriesUser.php

@ -9,7 +9,7 @@ namespace JKingWeb\Arsse\TestCase\Database;
use JKingWeb\Arsse\Arsse; use JKingWeb\Arsse\Arsse;
trait SeriesUser { trait SeriesUser {
protected function setUpSeriesUser():void { protected function setUpSeriesUser(): void {
$this->data = [ $this->data = [
'arsse_users' => [ 'arsse_users' => [
'columns' => [ 'columns' => [
@ -25,11 +25,11 @@ trait SeriesUser {
]; ];
} }
protected function tearDownSeriesUser():void { protected function tearDownSeriesUser(): void {
unset($this->data); unset($this->data);
} }
public function testCheckThatAUserExists():void { public function testCheckThatAUserExists(): void {
$this->assertTrue(Arsse::$db->userExists("jane.doe@example.com")); $this->assertTrue(Arsse::$db->userExists("jane.doe@example.com"));
$this->assertFalse(Arsse::$db->userExists("jane.doe@example.org")); $this->assertFalse(Arsse::$db->userExists("jane.doe@example.org"));
\Phake::verify(Arsse::$user)->authorize("jane.doe@example.com", "userExists"); \Phake::verify(Arsse::$user)->authorize("jane.doe@example.com", "userExists");
@ -37,31 +37,31 @@ trait SeriesUser {
$this->compareExpectations(static::$drv, $this->data); $this->compareExpectations(static::$drv, $this->data);
} }
public function testCheckThatAUserExistsWithoutAuthority():void { public function testCheckThatAUserExistsWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->userExists("jane.doe@example.com"); Arsse::$db->userExists("jane.doe@example.com");
} }
public function testGetAPassword():void { public function testGetAPassword(): void {
$hash = Arsse::$db->userPasswordGet("admin@example.net"); $hash = Arsse::$db->userPasswordGet("admin@example.net");
$this->assertSame('$2y$10$PbcG2ZR3Z8TuPzM7aHTF8.v61dtCjzjK78gdZJcp4UePE8T9jEgBW', $hash); $this->assertSame('$2y$10$PbcG2ZR3Z8TuPzM7aHTF8.v61dtCjzjK78gdZJcp4UePE8T9jEgBW', $hash);
\Phake::verify(Arsse::$user)->authorize("admin@example.net", "userPasswordGet"); \Phake::verify(Arsse::$user)->authorize("admin@example.net", "userPasswordGet");
$this->assertTrue(password_verify("secret", $hash)); $this->assertTrue(password_verify("secret", $hash));
} }
public function testGetThePasswordOfAMissingUser():void { public function testGetThePasswordOfAMissingUser(): void {
$this->assertException("doesNotExist", "User"); $this->assertException("doesNotExist", "User");
Arsse::$db->userPasswordGet("john.doe@example.org"); Arsse::$db->userPasswordGet("john.doe@example.org");
} }
public function testGetAPasswordWithoutAuthority():void { public function testGetAPasswordWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->userPasswordGet("admin@example.net"); Arsse::$db->userPasswordGet("admin@example.net");
} }
public function testAddANewUser():void { public function testAddANewUser(): void {
$this->assertTrue(Arsse::$db->userAdd("john.doe@example.org", "")); $this->assertTrue(Arsse::$db->userAdd("john.doe@example.org", ""));
\Phake::verify(Arsse::$user)->authorize("john.doe@example.org", "userAdd"); \Phake::verify(Arsse::$user)->authorize("john.doe@example.org", "userAdd");
$state = $this->primeExpectations($this->data, ['arsse_users' => ['id']]); $state = $this->primeExpectations($this->data, ['arsse_users' => ['id']]);
@ -69,18 +69,18 @@ trait SeriesUser {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testAddAnExistingUser():void { public function testAddAnExistingUser(): void {
$this->assertException("alreadyExists", "User"); $this->assertException("alreadyExists", "User");
Arsse::$db->userAdd("john.doe@example.com", ""); Arsse::$db->userAdd("john.doe@example.com", "");
} }
public function testAddANewUserWithoutAuthority():void { public function testAddANewUserWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->userAdd("john.doe@example.org", ""); Arsse::$db->userAdd("john.doe@example.org", "");
} }
public function testRemoveAUser():void { public function testRemoveAUser(): void {
$this->assertTrue(Arsse::$db->userRemove("admin@example.net")); $this->assertTrue(Arsse::$db->userRemove("admin@example.net"));
\Phake::verify(Arsse::$user)->authorize("admin@example.net", "userRemove"); \Phake::verify(Arsse::$user)->authorize("admin@example.net", "userRemove");
$state = $this->primeExpectations($this->data, ['arsse_users' => ['id']]); $state = $this->primeExpectations($this->data, ['arsse_users' => ['id']]);
@ -88,24 +88,24 @@ trait SeriesUser {
$this->compareExpectations(static::$drv, $state); $this->compareExpectations(static::$drv, $state);
} }
public function testRemoveAMissingUser():void { public function testRemoveAMissingUser(): void {
$this->assertException("doesNotExist", "User"); $this->assertException("doesNotExist", "User");
Arsse::$db->userRemove("john.doe@example.org"); Arsse::$db->userRemove("john.doe@example.org");
} }
public function testRemoveAUserWithoutAuthority():void { public function testRemoveAUserWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->userRemove("admin@example.net"); Arsse::$db->userRemove("admin@example.net");
} }
public function testListAllUsers():void { public function testListAllUsers(): void {
$users = ["admin@example.net", "jane.doe@example.com", "john.doe@example.com"]; $users = ["admin@example.net", "jane.doe@example.com", "john.doe@example.com"];
$this->assertSame($users, Arsse::$db->userList()); $this->assertSame($users, Arsse::$db->userList());
\Phake::verify(Arsse::$user)->authorize("", "userList"); \Phake::verify(Arsse::$user)->authorize("", "userList");
} }
public function testListAllUsersWithoutAuthority():void { public function testListAllUsersWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->userList(); Arsse::$db->userList();
@ -114,7 +114,7 @@ trait SeriesUser {
/** /**
* @depends testGetAPassword * @depends testGetAPassword
*/ */
public function testSetAPassword():void { public function testSetAPassword(): void {
$user = "john.doe@example.com"; $user = "john.doe@example.com";
$pass = "secret"; $pass = "secret";
$this->assertEquals("", Arsse::$db->userPasswordGet($user)); $this->assertEquals("", Arsse::$db->userPasswordGet($user));
@ -125,19 +125,19 @@ trait SeriesUser {
$this->assertTrue(password_verify($pass, $hash), "Failed verifying password of $user '$pass' against hash '$hash'."); $this->assertTrue(password_verify($pass, $hash), "Failed verifying password of $user '$pass' against hash '$hash'.");
} }
public function testUnsetAPassword():void { public function testUnsetAPassword(): void {
$user = "john.doe@example.com"; $user = "john.doe@example.com";
$this->assertEquals("", Arsse::$db->userPasswordGet($user)); $this->assertEquals("", Arsse::$db->userPasswordGet($user));
$this->assertTrue(Arsse::$db->userPasswordSet($user, null)); $this->assertTrue(Arsse::$db->userPasswordSet($user, null));
$this->assertNull(Arsse::$db->userPasswordGet($user)); $this->assertNull(Arsse::$db->userPasswordGet($user));
} }
public function testSetThePasswordOfAMissingUser():void { public function testSetThePasswordOfAMissingUser(): void {
$this->assertException("doesNotExist", "User"); $this->assertException("doesNotExist", "User");
Arsse::$db->userPasswordSet("john.doe@example.org", "secret"); Arsse::$db->userPasswordSet("john.doe@example.org", "secret");
} }
public function testSetAPasswordWithoutAuthority():void { public function testSetAPasswordWithoutAuthority(): void {
\Phake::when(Arsse::$user)->authorize->thenReturn(false); \Phake::when(Arsse::$user)->authorize->thenReturn(false);
$this->assertException("notAuthorized", "User", "ExceptionAuthz"); $this->assertException("notAuthorized", "User", "ExceptionAuthz");
Arsse::$db->userPasswordSet("john.doe@example.com", "secret"); Arsse::$db->userPasswordSet("john.doe@example.com", "secret");

4
tests/cases/Database/TestDatabase.php

@ -28,7 +28,7 @@ class TestDatabase extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideInClauses */ /** @dataProvider provideInClauses */
public function testGenerateInClause(string $clause, array $values, array $inV, string $inT):void { public function testGenerateInClause(string $clause, array $values, array $inV, string $inT): void {
$types = array_fill(0, sizeof($values), $inT); $types = array_fill(0, sizeof($values), $inT);
$exp = [$clause, $types, $values]; $exp = [$clause, $types, $values];
$this->assertSame($exp, $this->db->generateIn($inV, $inT)); $this->assertSame($exp, $this->db->generateIn($inV, $inT));
@ -62,7 +62,7 @@ class TestDatabase extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideSearchClauses */ /** @dataProvider provideSearchClauses */
public function testGenerateSearchClause(string $clause, array $values, array $inV, array $inC, bool $inAny):void { public function testGenerateSearchClause(string $clause, array $values, array $inV, array $inC, bool $inAny): void {
// this is not an exhaustive test; integration tests already cover the ins and outs of the functionality // this is not an exhaustive test; integration tests already cover the ins and outs of the functionality
$types = array_fill(0, sizeof($values), "str"); $types = array_fill(0, sizeof($values), "str");
$exp = [$clause, $types, $values]; $exp = [$clause, $types, $values];

70
tests/cases/Db/BaseDriver.php

@ -76,112 +76,112 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
# TESTS # TESTS
public function testFetchDriverName():void { public function testFetchDriverName(): void {
$class = get_class($this->drv); $class = get_class($this->drv);
$this->assertTrue(strlen($class::driverName()) > 0); $this->assertTrue(strlen($class::driverName()) > 0);
} }
public function testFetchSchemaId():void { public function testFetchSchemaId(): void {
$class = get_class($this->drv); $class = get_class($this->drv);
$this->assertTrue(strlen($class::schemaID()) > 0); $this->assertTrue(strlen($class::schemaID()) > 0);
} }
public function testCheckCharacterSetAcceptability():void { public function testCheckCharacterSetAcceptability(): void {
$this->assertTrue($this->drv->charsetAcceptable()); $this->assertTrue($this->drv->charsetAcceptable());
} }
public function testTranslateAToken():void { public function testTranslateAToken(): void {
$this->assertRegExp("/^[a-z][a-z0-9]*$/i", $this->drv->sqlToken("greatest")); $this->assertRegExp("/^[a-z][a-z0-9]*$/i", $this->drv->sqlToken("greatest"));
$this->assertRegExp("/^\"?[a-z][a-z0-9_\-]*\"?$/i", $this->drv->sqlToken("nocase")); $this->assertRegExp("/^\"?[a-z][a-z0-9_\-]*\"?$/i", $this->drv->sqlToken("nocase"));
$this->assertRegExp("/^[a-z][a-z0-9]*$/i", $this->drv->sqlToken("like")); $this->assertRegExp("/^[a-z][a-z0-9]*$/i", $this->drv->sqlToken("like"));
$this->assertSame("distinct", $this->drv->sqlToken("distinct")); $this->assertSame("distinct", $this->drv->sqlToken("distinct"));
} }
public function testExecAValidStatement():void { public function testExecAValidStatement(): void {
$this->assertTrue($this->drv->exec($this->create)); $this->assertTrue($this->drv->exec($this->create));
} }
public function testExecAnInvalidStatement():void { public function testExecAnInvalidStatement(): void {
$this->assertException("engineErrorGeneral", "Db"); $this->assertException("engineErrorGeneral", "Db");
$this->drv->exec("And the meek shall inherit the earth..."); $this->drv->exec("And the meek shall inherit the earth...");
} }
public function testExecMultipleStatements():void { public function testExecMultipleStatements(): void {
$this->assertTrue($this->drv->exec("$this->create; INSERT INTO arsse_test(id) values(2112)")); $this->assertTrue($this->drv->exec("$this->create; INSERT INTO arsse_test(id) values(2112)"));
$this->assertEquals(2112, $this->query("SELECT id from arsse_test")); $this->assertEquals(2112, $this->query("SELECT id from arsse_test"));
} }
public function testExecTimeout():void { public function testExecTimeout(): void {
$this->exec($this->create); $this->exec($this->create);
$this->exec($this->lock); $this->exec($this->lock);
$this->assertException("general", "Db", "ExceptionTimeout"); $this->assertException("general", "Db", "ExceptionTimeout");
$this->drv->exec("INSERT INTO arsse_meta(\"key\", value) values('lock', '1')"); $this->drv->exec("INSERT INTO arsse_meta(\"key\", value) values('lock', '1')");
} }
public function testExecConstraintViolation():void { public function testExecConstraintViolation(): void {
$this->drv->exec("CREATE TABLE arsse_test(id varchar(255) not null)"); $this->drv->exec("CREATE TABLE arsse_test(id varchar(255) not null)");
$this->assertException("constraintViolation", "Db", "ExceptionInput"); $this->assertException("constraintViolation", "Db", "ExceptionInput");
$this->drv->exec(static::$insertDefaultValues); $this->drv->exec(static::$insertDefaultValues);
} }
public function testExecTypeViolation():void { public function testExecTypeViolation(): void {
$this->drv->exec($this->create); $this->drv->exec($this->create);
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
$this->drv->exec("INSERT INTO arsse_test(id) values('ook')"); $this->drv->exec("INSERT INTO arsse_test(id) values('ook')");
} }
public function testMakeAValidQuery():void { public function testMakeAValidQuery(): void {
$this->assertInstanceOf(Result::class, $this->drv->query("SELECT 1")); $this->assertInstanceOf(Result::class, $this->drv->query("SELECT 1"));
} }
public function testMakeAnInvalidQuery():void { public function testMakeAnInvalidQuery(): void {
$this->assertException("engineErrorGeneral", "Db"); $this->assertException("engineErrorGeneral", "Db");
$this->drv->query("Apollo was astonished; Dionysus thought me mad"); $this->drv->query("Apollo was astonished; Dionysus thought me mad");
} }
public function testQueryConstraintViolation():void { public function testQueryConstraintViolation(): void {
$this->drv->exec("CREATE TABLE arsse_test(id integer not null)"); $this->drv->exec("CREATE TABLE arsse_test(id integer not null)");
$this->assertException("constraintViolation", "Db", "ExceptionInput"); $this->assertException("constraintViolation", "Db", "ExceptionInput");
$this->drv->query(static::$insertDefaultValues); $this->drv->query(static::$insertDefaultValues);
} }
public function testQueryTypeViolation():void { public function testQueryTypeViolation(): void {
$this->drv->exec($this->create); $this->drv->exec($this->create);
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");
$this->drv->query("INSERT INTO arsse_test(id) values('ook')"); $this->drv->query("INSERT INTO arsse_test(id) values('ook')");
} }
public function testPrepareAValidQuery():void { public function testPrepareAValidQuery(): void {
$s = $this->drv->prepare("SELECT ?, ?", "int", "int"); $s = $this->drv->prepare("SELECT ?, ?", "int", "int");
$this->assertInstanceOf(Statement::class, $s); $this->assertInstanceOf(Statement::class, $s);
} }
public function testPrepareAnInvalidQuery():void { public function testPrepareAnInvalidQuery(): void {
$this->assertException("engineErrorGeneral", "Db"); $this->assertException("engineErrorGeneral", "Db");
$s = $this->drv->prepare("This is an invalid query", "int", "int")->run(); $s = $this->drv->prepare("This is an invalid query", "int", "int")->run();
} }
public function testCreateASavepoint():void { public function testCreateASavepoint(): void {
$this->assertEquals(1, $this->drv->savepointCreate()); $this->assertEquals(1, $this->drv->savepointCreate());
$this->assertEquals(2, $this->drv->savepointCreate()); $this->assertEquals(2, $this->drv->savepointCreate());
$this->assertEquals(3, $this->drv->savepointCreate()); $this->assertEquals(3, $this->drv->savepointCreate());
} }
public function testReleaseASavepoint():void { public function testReleaseASavepoint(): void {
$this->assertEquals(1, $this->drv->savepointCreate()); $this->assertEquals(1, $this->drv->savepointCreate());
$this->assertEquals(true, $this->drv->savepointRelease()); $this->assertEquals(true, $this->drv->savepointRelease());
$this->assertException("savepointInvalid", "Db"); $this->assertException("savepointInvalid", "Db");
$this->drv->savepointRelease(); $this->drv->savepointRelease();
} }
public function testUndoASavepoint():void { public function testUndoASavepoint(): void {
$this->assertEquals(1, $this->drv->savepointCreate()); $this->assertEquals(1, $this->drv->savepointCreate());
$this->assertEquals(true, $this->drv->savepointUndo()); $this->assertEquals(true, $this->drv->savepointUndo());
$this->assertException("savepointInvalid", "Db"); $this->assertException("savepointInvalid", "Db");
$this->drv->savepointUndo(); $this->drv->savepointUndo();
} }
public function testManipulateSavepoints():void { public function testManipulateSavepoints(): void {
$this->assertEquals(1, $this->drv->savepointCreate()); $this->assertEquals(1, $this->drv->savepointCreate());
$this->assertEquals(2, $this->drv->savepointCreate()); $this->assertEquals(2, $this->drv->savepointCreate());
$this->assertEquals(3, $this->drv->savepointCreate()); $this->assertEquals(3, $this->drv->savepointCreate());
@ -198,7 +198,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
$this->drv->savepointRelease(2); $this->drv->savepointRelease(2);
} }
public function testManipulateSavepointsSomeMore():void { public function testManipulateSavepointsSomeMore(): void {
$this->assertEquals(1, $this->drv->savepointCreate()); $this->assertEquals(1, $this->drv->savepointCreate());
$this->assertEquals(2, $this->drv->savepointCreate()); $this->assertEquals(2, $this->drv->savepointCreate());
$this->assertEquals(3, $this->drv->savepointCreate()); $this->assertEquals(3, $this->drv->savepointCreate());
@ -209,7 +209,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
$this->drv->savepointUndo(2); $this->drv->savepointUndo(2);
} }
public function testBeginATransaction():void { public function testBeginATransaction(): void {
$select = "SELECT count(*) FROM arsse_test"; $select = "SELECT count(*) FROM arsse_test";
$this->drv->exec($this->create); $this->drv->exec($this->create);
$tr = $this->drv->begin(); $tr = $this->drv->begin();
@ -221,7 +221,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertEquals(0, $this->query($select)); $this->assertEquals(0, $this->query($select));
} }
public function testCommitATransaction():void { public function testCommitATransaction(): void {
$select = "SELECT count(*) FROM arsse_test"; $select = "SELECT count(*) FROM arsse_test";
$this->drv->exec($this->create); $this->drv->exec($this->create);
$tr = $this->drv->begin(); $tr = $this->drv->begin();
@ -233,7 +233,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertEquals(1, $this->query($select)); $this->assertEquals(1, $this->query($select));
} }
public function testRollbackATransaction():void { public function testRollbackATransaction(): void {
$select = "SELECT count(*) FROM arsse_test"; $select = "SELECT count(*) FROM arsse_test";
$this->drv->exec($this->create); $this->drv->exec($this->create);
$tr = $this->drv->begin(); $tr = $this->drv->begin();
@ -245,7 +245,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertEquals(0, $this->query($select)); $this->assertEquals(0, $this->query($select));
} }
public function testBeginChainedTransactions():void { public function testBeginChainedTransactions(): void {
$select = "SELECT count(*) FROM arsse_test"; $select = "SELECT count(*) FROM arsse_test";
$this->drv->exec($this->create); $this->drv->exec($this->create);
$tr1 = $this->drv->begin(); $tr1 = $this->drv->begin();
@ -258,7 +258,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertEquals(0, $this->query($select)); $this->assertEquals(0, $this->query($select));
} }
public function testCommitChainedTransactions():void { public function testCommitChainedTransactions(): void {
$select = "SELECT count(*) FROM arsse_test"; $select = "SELECT count(*) FROM arsse_test";
$this->drv->exec($this->create); $this->drv->exec($this->create);
$tr1 = $this->drv->begin(); $tr1 = $this->drv->begin();
@ -275,7 +275,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertEquals(2, $this->query($select)); $this->assertEquals(2, $this->query($select));
} }
public function testCommitChainedTransactionsOutOfOrder():void { public function testCommitChainedTransactionsOutOfOrder(): void {
$select = "SELECT count(*) FROM arsse_test"; $select = "SELECT count(*) FROM arsse_test";
$this->drv->exec($this->create); $this->drv->exec($this->create);
$tr1 = $this->drv->begin(); $tr1 = $this->drv->begin();
@ -291,7 +291,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
$tr2->commit(); $tr2->commit();
} }
public function testRollbackChainedTransactions():void { public function testRollbackChainedTransactions(): void {
$select = "SELECT count(*) FROM arsse_test"; $select = "SELECT count(*) FROM arsse_test";
$this->drv->exec($this->create); $this->drv->exec($this->create);
$tr1 = $this->drv->begin(); $tr1 = $this->drv->begin();
@ -310,7 +310,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertEquals(0, $this->query($select)); $this->assertEquals(0, $this->query($select));
} }
public function testRollbackChainedTransactionsOutOfOrder():void { public function testRollbackChainedTransactionsOutOfOrder(): void {
$select = "SELECT count(*) FROM arsse_test"; $select = "SELECT count(*) FROM arsse_test";
$this->drv->exec($this->create); $this->drv->exec($this->create);
$tr1 = $this->drv->begin(); $tr1 = $this->drv->begin();
@ -329,7 +329,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertEquals(0, $this->query($select)); $this->assertEquals(0, $this->query($select));
} }
public function testPartiallyRollbackChainedTransactions():void { public function testPartiallyRollbackChainedTransactions(): void {
$select = "SELECT count(*) FROM arsse_test"; $select = "SELECT count(*) FROM arsse_test";
$this->drv->exec($this->create); $this->drv->exec($this->create);
$tr1 = $this->drv->begin(); $tr1 = $this->drv->begin();
@ -348,7 +348,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertEquals(1, $this->query($select)); $this->assertEquals(1, $this->query($select));
} }
public function testFetchSchemaVersion():void { public function testFetchSchemaVersion(): void {
$this->assertSame(0, $this->drv->schemaVersion()); $this->assertSame(0, $this->drv->schemaVersion());
$this->drv->exec(str_replace("#", "1", $this->setVersion)); $this->drv->exec(str_replace("#", "1", $this->setVersion));
$this->assertSame(1, $this->drv->schemaVersion()); $this->assertSame(1, $this->drv->schemaVersion());
@ -361,7 +361,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame($exp, $this->drv->schemaVersion()); $this->assertSame($exp, $this->drv->schemaVersion());
} }
public function testLockTheDatabase():void { public function testLockTheDatabase(): void {
// PostgreSQL doesn't actually lock the whole database, only the metadata table // PostgreSQL doesn't actually lock the whole database, only the metadata table
// normally the application will first query this table to ensure the schema version is correct, // normally the application will first query this table to ensure the schema version is correct,
// so the effect is usually the same // so the effect is usually the same
@ -370,7 +370,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
$this->exec($this->lock); $this->exec($this->lock);
} }
public function testUnlockTheDatabase():void { public function testUnlockTheDatabase(): void {
$this->drv->savepointCreate(true); $this->drv->savepointCreate(true);
$this->drv->savepointRelease(); $this->drv->savepointRelease();
$this->drv->savepointCreate(true); $this->drv->savepointCreate(true);
@ -378,11 +378,11 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertTrue($this->exec(str_replace("#", "3", $this->setVersion))); $this->assertTrue($this->exec(str_replace("#", "3", $this->setVersion)));
} }
public function testProduceAStringLiteral():void { public function testProduceAStringLiteral(): void {
$this->assertSame("'It''s a string!'", $this->drv->literalString("It's a string!")); $this->assertSame("'It''s a string!'", $this->drv->literalString("It's a string!"));
} }
public function testPerformMaintenance():void { public function testPerformMaintenance(): void {
// this performs maintenance in the absence of tables; see BaseUpdate.php for another test with tables // this performs maintenance in the absence of tables; see BaseUpdate.php for another test with tables
$this->assertTrue($this->drv->maintenance()); $this->assertTrue($this->drv->maintenance());
} }

18
tests/cases/Db/BaseResult.php

@ -46,18 +46,18 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
self::clearData(); self::clearData();
} }
public function testConstructResult():void { public function testConstructResult(): void {
$this->assertInstanceOf(Result::class, new $this->resultClass(...$this->makeResult("SELECT 1"))); $this->assertInstanceOf(Result::class, new $this->resultClass(...$this->makeResult("SELECT 1")));
} }
public function testGetChangeCountAndLastInsertId():void { public function testGetChangeCountAndLastInsertId(): void {
$this->makeResult(static::$createMeta); $this->makeResult(static::$createMeta);
$r = new $this->resultClass(...$this->makeResult("INSERT INTO arsse_meta(\"key\",value) values('test', 1)")); $r = new $this->resultClass(...$this->makeResult("INSERT INTO arsse_meta(\"key\",value) values('test', 1)"));
$this->assertSame(1, $r->changes()); $this->assertSame(1, $r->changes());
$this->assertSame(0, $r->lastId()); $this->assertSame(0, $r->lastId());
} }
public function testGetChangeCountAndLastInsertIdBis():void { public function testGetChangeCountAndLastInsertIdBis(): void {
$this->makeResult(static::$createTest); $this->makeResult(static::$createTest);
$r = new $this->resultClass(...$this->makeResult(static::$insertDefault)); $r = new $this->resultClass(...$this->makeResult(static::$insertDefault));
$this->assertSame(1, $r->changes()); $this->assertSame(1, $r->changes());
@ -67,7 +67,7 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame(2, $r->lastId()); $this->assertSame(2, $r->lastId());
} }
public function testIterateOverResults():void { public function testIterateOverResults(): void {
$exp = [0 => 1, 1 => 2, 2 => 3]; $exp = [0 => 1, 1 => 2, 2 => 3];
$exp = static::$stringOutput ? $this->stringify($exp) : $exp; $exp = static::$stringOutput ? $this->stringify($exp) : $exp;
foreach (new $this->resultClass(...$this->makeResult("SELECT 1 as col union select 2 as col union select 3 as col")) as $index => $row) { foreach (new $this->resultClass(...$this->makeResult("SELECT 1 as col union select 2 as col union select 3 as col")) as $index => $row) {
@ -76,7 +76,7 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame($exp, $rows); $this->assertSame($exp, $rows);
} }
public function testIterateOverResultsTwice():void { public function testIterateOverResultsTwice(): void {
$exp = [0 => 1, 1 => 2, 2 => 3]; $exp = [0 => 1, 1 => 2, 2 => 3];
$exp = static::$stringOutput ? $this->stringify($exp) : $exp; $exp = static::$stringOutput ? $this->stringify($exp) : $exp;
$result = new $this->resultClass(...$this->makeResult("SELECT 1 as col union select 2 as col union select 3 as col")); $result = new $this->resultClass(...$this->makeResult("SELECT 1 as col union select 2 as col union select 3 as col"));
@ -90,7 +90,7 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
} }
} }
public function testGetSingleValues():void { public function testGetSingleValues(): void {
$exp = [1867, 1970, 2112]; $exp = [1867, 1970, 2112];
$exp = static::$stringOutput ? $this->stringify($exp) : $exp; $exp = static::$stringOutput ? $this->stringify($exp) : $exp;
$test = new $this->resultClass(...$this->makeResult("SELECT 1867 as year union all select 1970 as year union all select 2112 as year")); $test = new $this->resultClass(...$this->makeResult("SELECT 1867 as year union all select 1970 as year union all select 2112 as year"));
@ -100,7 +100,7 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame(null, $test->getValue()); $this->assertSame(null, $test->getValue());
} }
public function testGetFirstValuesOnly():void { public function testGetFirstValuesOnly(): void {
$exp = [1867, 1970, 2112]; $exp = [1867, 1970, 2112];
$exp = static::$stringOutput ? $this->stringify($exp) : $exp; $exp = static::$stringOutput ? $this->stringify($exp) : $exp;
$test = new $this->resultClass(...$this->makeResult("SELECT 1867 as year, 19 as century union all select 1970 as year, 20 as century union all select 2112 as year, 22 as century")); $test = new $this->resultClass(...$this->makeResult("SELECT 1867 as year, 19 as century union all select 1970 as year, 20 as century union all select 2112 as year, 22 as century"));
@ -110,7 +110,7 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame(null, $test->getValue()); $this->assertSame(null, $test->getValue());
} }
public function testGetRows():void { public function testGetRows(): void {
$exp = [ $exp = [
['album' => '2112', 'track' => '2112'], ['album' => '2112', 'track' => '2112'],
['album' => 'Clockwork Angels', 'track' => 'The Wreckers'], ['album' => 'Clockwork Angels', 'track' => 'The Wreckers'],
@ -121,7 +121,7 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame(null, $test->getRow()); $this->assertSame(null, $test->getRow());
} }
public function testGetAllRows():void { public function testGetAllRows(): void {
$exp = [ $exp = [
['album' => '2112', 'track' => '2112'], ['album' => '2112', 'track' => '2112'],
['album' => 'Clockwork Angels', 'track' => 'The Wreckers'], ['album' => 'Clockwork Angels', 'track' => 'The Wreckers'],

18
tests/cases/Db/BaseStatement.php

@ -46,12 +46,12 @@ abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest {
self::clearData(); self::clearData();
} }
public function testConstructStatement():void { public function testConstructStatement(): void {
$this->assertInstanceOf(Statement::class, new $this->statementClass(...$this->makeStatement("SELECT ? as value"))); $this->assertInstanceOf(Statement::class, new $this->statementClass(...$this->makeStatement("SELECT ? as value")));
} }
/** @dataProvider provideBindings */ /** @dataProvider provideBindings */
public function testBindATypedValue($value, string $type, string $exp):void { public function testBindATypedValue($value, string $type, string $exp): void {
if ($exp === "null") { if ($exp === "null") {
$query = "SELECT (? is null) as pass"; $query = "SELECT (? is null) as pass";
} else { } else {
@ -65,7 +65,7 @@ abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideBinaryBindings */ /** @dataProvider provideBinaryBindings */
public function testHandleBinaryData($value, string $type, string $exp):void { public function testHandleBinaryData($value, string $type, string $exp): void {
if (in_array(static::$implementation, ["PostgreSQL", "PDO PostgreSQL"])) { if (in_array(static::$implementation, ["PostgreSQL", "PDO PostgreSQL"])) {
$this->markTestIncomplete("Correct handling of binary data with PostgreSQL is not currently implemented"); $this->markTestIncomplete("Correct handling of binary data with PostgreSQL is not currently implemented");
} }
@ -81,13 +81,13 @@ abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertTrue((bool) $act); $this->assertTrue((bool) $act);
} }
public function testBindMissingValue():void { public function testBindMissingValue(): void {
$s = new $this->statementClass(...$this->makeStatement("SELECT ? as value", ["int"])); $s = new $this->statementClass(...$this->makeStatement("SELECT ? as value", ["int"]));
$val = $s->runArray()->getRow()['value']; $val = $s->runArray()->getRow()['value'];
$this->assertSame(null, $val); $this->assertSame(null, $val);
} }
public function testBindMultipleValues():void { public function testBindMultipleValues(): void {
$exp = [ $exp = [
'one' => "A", 'one' => "A",
'two' => "B", 'two' => "B",
@ -97,7 +97,7 @@ abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame($exp, $val); $this->assertSame($exp, $val);
} }
public function testBindRecursively():void { public function testBindRecursively(): void {
$exp = [ $exp = [
'one' => "A", 'one' => "A",
'two' => "B", 'two' => "B",
@ -109,20 +109,20 @@ abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame($exp, $val); $this->assertSame($exp, $val);
} }
public function testBindWithoutType():void { public function testBindWithoutType(): void {
$this->assertException("paramTypeMissing", "Db"); $this->assertException("paramTypeMissing", "Db");
$s = new $this->statementClass(...$this->makeStatement("SELECT ? as value", [])); $s = new $this->statementClass(...$this->makeStatement("SELECT ? as value", []));
$s->runArray([1]); $s->runArray([1]);
} }
public function testViolateConstraint():void { public function testViolateConstraint(): void {
(new $this->statementClass(...$this->makeStatement("CREATE TABLE if not exists arsse_meta(\"key\" varchar(255) primary key not null, value text)")))->run(); (new $this->statementClass(...$this->makeStatement("CREATE TABLE if not exists arsse_meta(\"key\" varchar(255) primary key not null, value text)")))->run();
$s = new $this->statementClass(...$this->makeStatement("INSERT INTO arsse_meta(\"key\") values(?)", ["str"])); $s = new $this->statementClass(...$this->makeStatement("INSERT INTO arsse_meta(\"key\") values(?)", ["str"]));
$this->assertException("constraintViolation", "Db", "ExceptionInput"); $this->assertException("constraintViolation", "Db", "ExceptionInput");
$s->runArray([null]); $s->runArray([null]);
} }
public function testMismatchTypes():void { public function testMismatchTypes(): void {
(new $this->statementClass(...$this->makeStatement("CREATE TABLE if not exists arsse_feeds(id integer primary key not null, url text not null)")))->run(); (new $this->statementClass(...$this->makeStatement("CREATE TABLE if not exists arsse_feeds(id integer primary key not null, url text not null)")))->run();
$s = new $this->statementClass(...$this->makeStatement("INSERT INTO arsse_feeds(id,url) values(?,?)", ["str", "str"])); $s = new $this->statementClass(...$this->makeStatement("INSERT INTO arsse_feeds(id,url) values(?,?)", ["str", "str"]));
$this->assertException("typeViolation", "Db", "ExceptionInput"); $this->assertException("typeViolation", "Db", "ExceptionInput");

24
tests/cases/Db/BaseUpdate.php

@ -58,43 +58,43 @@ class BaseUpdate extends \JKingWeb\Arsse\Test\AbstractTest {
self::clearData(); self::clearData();
} }
public function testLoadMissingFile():void { public function testLoadMissingFile(): void {
$this->assertException("updateFileMissing", "Db"); $this->assertException("updateFileMissing", "Db");
$this->drv->schemaUpdate(1, $this->base); $this->drv->schemaUpdate(1, $this->base);
} }
public function testLoadUnreadableFile():void { public function testLoadUnreadableFile(): void {
touch($this->path."0.sql"); touch($this->path."0.sql");
chmod($this->path."0.sql", 0000); chmod($this->path."0.sql", 0000);
$this->assertException("updateFileUnreadable", "Db"); $this->assertException("updateFileUnreadable", "Db");
$this->drv->schemaUpdate(1, $this->base); $this->drv->schemaUpdate(1, $this->base);
} }
public function testLoadCorruptFile():void { public function testLoadCorruptFile(): void {
file_put_contents($this->path."0.sql", "This is a corrupt file"); file_put_contents($this->path."0.sql", "This is a corrupt file");
$this->assertException("updateFileError", "Db"); $this->assertException("updateFileError", "Db");
$this->drv->schemaUpdate(1, $this->base); $this->drv->schemaUpdate(1, $this->base);
} }
public function testLoadIncompleteFile():void { public function testLoadIncompleteFile(): void {
file_put_contents($this->path."0.sql", "create table arsse_meta(\"key\" varchar(255) primary key not null, value text);"); file_put_contents($this->path."0.sql", "create table arsse_meta(\"key\" varchar(255) primary key not null, value text);");
$this->assertException("updateFileIncomplete", "Db"); $this->assertException("updateFileIncomplete", "Db");
$this->drv->schemaUpdate(1, $this->base); $this->drv->schemaUpdate(1, $this->base);
} }
public function testLoadEmptyFile():void { public function testLoadEmptyFile(): void {
file_put_contents($this->path."0.sql", ""); file_put_contents($this->path."0.sql", "");
$this->assertException("updateFileIncomplete", "Db"); $this->assertException("updateFileIncomplete", "Db");
$this->drv->schemaUpdate(1, $this->base); $this->drv->schemaUpdate(1, $this->base);
} }
public function testLoadCorrectFile():void { public function testLoadCorrectFile(): void {
file_put_contents($this->path."0.sql", static::$minimal1); file_put_contents($this->path."0.sql", static::$minimal1);
$this->drv->schemaUpdate(1, $this->base); $this->drv->schemaUpdate(1, $this->base);
$this->assertEquals(1, $this->drv->schemaVersion()); $this->assertEquals(1, $this->drv->schemaVersion());
} }
public function testPerformPartialUpdate():void { public function testPerformPartialUpdate(): void {
file_put_contents($this->path."0.sql", static::$minimal1); file_put_contents($this->path."0.sql", static::$minimal1);
file_put_contents($this->path."1.sql", "UPDATE arsse_meta set value = '1' where \"key\" = 'schema_version'"); file_put_contents($this->path."1.sql", "UPDATE arsse_meta set value = '1' where \"key\" = 'schema_version'");
$this->assertException("updateFileIncomplete", "Db"); $this->assertException("updateFileIncomplete", "Db");
@ -106,31 +106,31 @@ class BaseUpdate extends \JKingWeb\Arsse\Test\AbstractTest {
} }
} }
public function testPerformSequentialUpdate():void { public function testPerformSequentialUpdate(): void {
file_put_contents($this->path."0.sql", static::$minimal1); file_put_contents($this->path."0.sql", static::$minimal1);
file_put_contents($this->path."1.sql", static::$minimal2); file_put_contents($this->path."1.sql", static::$minimal2);
$this->drv->schemaUpdate(2, $this->base); $this->drv->schemaUpdate(2, $this->base);
$this->assertEquals(2, $this->drv->schemaVersion()); $this->assertEquals(2, $this->drv->schemaVersion());
} }
public function testPerformActualUpdate():void { public function testPerformActualUpdate(): void {
$this->drv->schemaUpdate(Database::SCHEMA_VERSION); $this->drv->schemaUpdate(Database::SCHEMA_VERSION);
$this->assertEquals(Database::SCHEMA_VERSION, $this->drv->schemaVersion()); $this->assertEquals(Database::SCHEMA_VERSION, $this->drv->schemaVersion());
} }
public function testDeclineManualUpdate():void { public function testDeclineManualUpdate(): void {
// turn auto-updating off // turn auto-updating off
Arsse::$conf->dbAutoUpdate = false; Arsse::$conf->dbAutoUpdate = false;
$this->assertException("updateManual", "Db"); $this->assertException("updateManual", "Db");
$this->drv->schemaUpdate(Database::SCHEMA_VERSION); $this->drv->schemaUpdate(Database::SCHEMA_VERSION);
} }
public function testDeclineDowngrade():void { public function testDeclineDowngrade(): void {
$this->assertException("updateTooNew", "Db"); $this->assertException("updateTooNew", "Db");
$this->drv->schemaUpdate(-1, $this->base); $this->drv->schemaUpdate(-1, $this->base);
} }
public function testPerformMaintenance():void { public function testPerformMaintenance(): void {
$this->drv->schemaUpdate(Database::SCHEMA_VERSION); $this->drv->schemaUpdate(Database::SCHEMA_VERSION);
$this->assertTrue($this->drv->maintenance()); $this->assertTrue($this->drv->maintenance());
} }

2
tests/cases/Db/MySQL/TestCreation.php

@ -19,7 +19,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
} }
} }
public function testFailToConnect():void { public function testFailToConnect(): void {
// for the sake of simplicity we don't distinguish between failure modes, but the MySQL-supplied error messages do // for the sake of simplicity we don't distinguish between failure modes, but the MySQL-supplied error messages do
self::setConf([ self::setConf([
'dbMySQLHost' => "example.invalid", 'dbMySQLHost' => "example.invalid",

2
tests/cases/Db/MySQL/TestStatement.php

@ -34,7 +34,7 @@ class TestStatement extends \JKingWeb\Arsse\TestCase\Db\BaseStatement {
} }
} }
public function testBindLongString():void { public function testBindLongString(): void {
// this test requires some set-up to be effective // this test requires some set-up to be effective
static::$interface->query("CREATE TABLE arsse_test(`value` longtext not null) character set utf8mb4"); static::$interface->query("CREATE TABLE arsse_test(`value` longtext not null) character set utf8mb4");
// we'll use an unrealistic packet size of 1 byte to trigger special handling for strings which are too long for the maximum packet size // we'll use an unrealistic packet size of 1 byte to trigger special handling for strings which are too long for the maximum packet size

2
tests/cases/Db/MySQLPDO/TestCreation.php

@ -19,7 +19,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
} }
} }
public function testFailToConnect():void { public function testFailToConnect(): void {
// for the sake of simplicity we don't distinguish between failure modes, but the MySQL-supplied error messages do // for the sake of simplicity we don't distinguish between failure modes, but the MySQL-supplied error messages do
self::setConf([ self::setConf([
'dbMySQLHost' => "example.invalid", 'dbMySQLHost' => "example.invalid",

4
tests/cases/Db/PostgreSQL/TestCreation.php

@ -20,7 +20,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideConnectionStrings */ /** @dataProvider provideConnectionStrings */
public function testGenerateConnectionString(bool $pdo, string $user, string $pass, string $db, string $host, int $port, string $service, string $exp):void { public function testGenerateConnectionString(bool $pdo, string $user, string $pass, string $db, string $host, int $port, string $service, string $exp): void {
self::setConf(); self::setConf();
$timeout = (string) ceil(Arsse::$conf->dbTimeoutConnect ?? 0); $timeout = (string) ceil(Arsse::$conf->dbTimeoutConnect ?? 0);
$postfix = "application_name='arsse' client_encoding='UTF8' connect_timeout='$timeout'"; $postfix = "application_name='arsse' client_encoding='UTF8' connect_timeout='$timeout'";
@ -62,7 +62,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
]; ];
} }
public function testFailToConnect():void { public function testFailToConnect(): void {
// we cannnot distinguish between different connection failure modes // we cannnot distinguish between different connection failure modes
self::setConf([ self::setConf([
'dbPostgreSQLHost' => "example.invalid", 'dbPostgreSQLHost' => "example.invalid",

4
tests/cases/Db/PostgreSQLPDO/TestCreation.php

@ -20,7 +20,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideConnectionStrings */ /** @dataProvider provideConnectionStrings */
public function testGenerateConnectionString(bool $pdo, string $user, string $pass, string $db, string $host, int $port, string $service, string $exp):void { public function testGenerateConnectionString(bool $pdo, string $user, string $pass, string $db, string $host, int $port, string $service, string $exp): void {
self::setConf(); self::setConf();
$timeout = (string) ceil(Arsse::$conf->dbTimeoutConnect ?? 0); $timeout = (string) ceil(Arsse::$conf->dbTimeoutConnect ?? 0);
$postfix = "application_name='arsse' client_encoding='UTF8' connect_timeout='$timeout'"; $postfix = "application_name='arsse' client_encoding='UTF8' connect_timeout='$timeout'";
@ -62,7 +62,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
]; ];
} }
public function testFailToConnect():void { public function testFailToConnect(): void {
// PDO dies not distinguish between different connection failure modes // PDO dies not distinguish between different connection failure modes
self::setConf([ self::setConf([
'dbPostgreSQLHost' => "example.invalid", 'dbPostgreSQLHost' => "example.invalid",

26
tests/cases/Db/SQLite3/TestCreation.php

@ -112,79 +112,79 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
self::clearData(); self::clearData();
} }
public function testFailToCreateDatabase():void { public function testFailToCreateDatabase(): void {
Arsse::$conf->dbSQLite3File = $this->path."Cmain/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Cmain/arsse.db";
$this->assertException("fileUncreatable", "Db"); $this->assertException("fileUncreatable", "Db");
new Driver; new Driver;
} }
public function testFailToCreateJournal():void { public function testFailToCreateJournal(): void {
Arsse::$conf->dbSQLite3File = $this->path."Cwal/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Cwal/arsse.db";
$this->assertException("fileUncreatable", "Db"); $this->assertException("fileUncreatable", "Db");
new Driver; new Driver;
} }
public function testFailToCreateSharedMmeory():void { public function testFailToCreateSharedMmeory(): void {
Arsse::$conf->dbSQLite3File = $this->path."Cshm/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Cshm/arsse.db";
$this->assertException("fileUncreatable", "Db"); $this->assertException("fileUncreatable", "Db");
new Driver; new Driver;
} }
public function testFailToReadDatabase():void { public function testFailToReadDatabase(): void {
Arsse::$conf->dbSQLite3File = $this->path."Rmain/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Rmain/arsse.db";
$this->assertException("fileUnreadable", "Db"); $this->assertException("fileUnreadable", "Db");
new Driver; new Driver;
} }
public function testFailToReadJournal():void { public function testFailToReadJournal(): void {
Arsse::$conf->dbSQLite3File = $this->path."Rwal/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Rwal/arsse.db";
$this->assertException("fileUnreadable", "Db"); $this->assertException("fileUnreadable", "Db");
new Driver; new Driver;
} }
public function testFailToReadSharedMmeory():void { public function testFailToReadSharedMmeory(): void {
Arsse::$conf->dbSQLite3File = $this->path."Rshm/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Rshm/arsse.db";
$this->assertException("fileUnreadable", "Db"); $this->assertException("fileUnreadable", "Db");
new Driver; new Driver;
} }
public function testFailToWriteToDatabase():void { public function testFailToWriteToDatabase(): void {
Arsse::$conf->dbSQLite3File = $this->path."Wmain/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Wmain/arsse.db";
$this->assertException("fileUnwritable", "Db"); $this->assertException("fileUnwritable", "Db");
new Driver; new Driver;
} }
public function testFailToWriteToJournal():void { public function testFailToWriteToJournal(): void {
Arsse::$conf->dbSQLite3File = $this->path."Wwal/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Wwal/arsse.db";
$this->assertException("fileUnwritable", "Db"); $this->assertException("fileUnwritable", "Db");
new Driver; new Driver;
} }
public function testFailToWriteToSharedMmeory():void { public function testFailToWriteToSharedMmeory(): void {
Arsse::$conf->dbSQLite3File = $this->path."Wshm/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Wshm/arsse.db";
$this->assertException("fileUnwritable", "Db"); $this->assertException("fileUnwritable", "Db");
new Driver; new Driver;
} }
public function testFailToAccessDatabase():void { public function testFailToAccessDatabase(): void {
Arsse::$conf->dbSQLite3File = $this->path."Amain/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Amain/arsse.db";
$this->assertException("fileUnusable", "Db"); $this->assertException("fileUnusable", "Db");
new Driver; new Driver;
} }
public function testFailToAccessJournal():void { public function testFailToAccessJournal(): void {
Arsse::$conf->dbSQLite3File = $this->path."Awal/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Awal/arsse.db";
$this->assertException("fileUnusable", "Db"); $this->assertException("fileUnusable", "Db");
new Driver; new Driver;
} }
public function testFailToAccessSharedMmeory():void { public function testFailToAccessSharedMmeory(): void {
Arsse::$conf->dbSQLite3File = $this->path."Ashm/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Ashm/arsse.db";
$this->assertException("fileUnusable", "Db"); $this->assertException("fileUnusable", "Db");
new Driver; new Driver;
} }
public function testAssumeDatabaseCorruption():void { public function testAssumeDatabaseCorruption(): void {
Arsse::$conf->dbSQLite3File = $this->path."corrupt/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."corrupt/arsse.db";
$this->assertException("fileCorrupt", "Db"); $this->assertException("fileCorrupt", "Db");
new Driver; new Driver;

26
tests/cases/Db/SQLite3PDO/TestCreation.php

@ -114,79 +114,79 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
self::clearData(); self::clearData();
} }
public function testFailToCreateDatabase():void { public function testFailToCreateDatabase(): void {
Arsse::$conf->dbSQLite3File = $this->path."Cmain/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Cmain/arsse.db";
$this->assertException("fileUncreatable", "Db"); $this->assertException("fileUncreatable", "Db");
new Driver; new Driver;
} }
public function testFailToCreateJournal():void { public function testFailToCreateJournal(): void {
Arsse::$conf->dbSQLite3File = $this->path."Cwal/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Cwal/arsse.db";
$this->assertException("fileUncreatable", "Db"); $this->assertException("fileUncreatable", "Db");
new Driver; new Driver;
} }
public function testFailToCreateSharedMmeory():void { public function testFailToCreateSharedMmeory(): void {
Arsse::$conf->dbSQLite3File = $this->path."Cshm/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Cshm/arsse.db";
$this->assertException("fileUncreatable", "Db"); $this->assertException("fileUncreatable", "Db");
new Driver; new Driver;
} }
public function testFailToReadDatabase():void { public function testFailToReadDatabase(): void {
Arsse::$conf->dbSQLite3File = $this->path."Rmain/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Rmain/arsse.db";
$this->assertException("fileUnreadable", "Db"); $this->assertException("fileUnreadable", "Db");
new Driver; new Driver;
} }
public function testFailToReadJournal():void { public function testFailToReadJournal(): void {
Arsse::$conf->dbSQLite3File = $this->path."Rwal/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Rwal/arsse.db";
$this->assertException("fileUnreadable", "Db"); $this->assertException("fileUnreadable", "Db");
new Driver; new Driver;
} }
public function testFailToReadSharedMmeory():void { public function testFailToReadSharedMmeory(): void {
Arsse::$conf->dbSQLite3File = $this->path."Rshm/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Rshm/arsse.db";
$this->assertException("fileUnreadable", "Db"); $this->assertException("fileUnreadable", "Db");
new Driver; new Driver;
} }
public function testFailToWriteToDatabase():void { public function testFailToWriteToDatabase(): void {
Arsse::$conf->dbSQLite3File = $this->path."Wmain/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Wmain/arsse.db";
$this->assertException("fileUnwritable", "Db"); $this->assertException("fileUnwritable", "Db");
new Driver; new Driver;
} }
public function testFailToWriteToJournal():void { public function testFailToWriteToJournal(): void {
Arsse::$conf->dbSQLite3File = $this->path."Wwal/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Wwal/arsse.db";
$this->assertException("fileUnwritable", "Db"); $this->assertException("fileUnwritable", "Db");
new Driver; new Driver;
} }
public function testFailToWriteToSharedMmeory():void { public function testFailToWriteToSharedMmeory(): void {
Arsse::$conf->dbSQLite3File = $this->path."Wshm/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Wshm/arsse.db";
$this->assertException("fileUnwritable", "Db"); $this->assertException("fileUnwritable", "Db");
new Driver; new Driver;
} }
public function testFailToAccessDatabase():void { public function testFailToAccessDatabase(): void {
Arsse::$conf->dbSQLite3File = $this->path."Amain/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Amain/arsse.db";
$this->assertException("fileUnusable", "Db"); $this->assertException("fileUnusable", "Db");
new Driver; new Driver;
} }
public function testFailToAccessJournal():void { public function testFailToAccessJournal(): void {
Arsse::$conf->dbSQLite3File = $this->path."Awal/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Awal/arsse.db";
$this->assertException("fileUnusable", "Db"); $this->assertException("fileUnusable", "Db");
new Driver; new Driver;
} }
public function testFailToAccessSharedMmeory():void { public function testFailToAccessSharedMmeory(): void {
Arsse::$conf->dbSQLite3File = $this->path."Ashm/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."Ashm/arsse.db";
$this->assertException("fileUnusable", "Db"); $this->assertException("fileUnusable", "Db");
new Driver; new Driver;
} }
public function testAssumeDatabaseCorruption():void { public function testAssumeDatabaseCorruption(): void {
Arsse::$conf->dbSQLite3File = $this->path."corrupt/arsse.db"; Arsse::$conf->dbSQLite3File = $this->path."corrupt/arsse.db";
$this->assertException("fileCorrupt", "Db"); $this->assertException("fileCorrupt", "Db");
new Driver; new Driver;

14
tests/cases/Db/TestResultAggregate.php

@ -7,7 +7,7 @@ use JKingWeb\Arsse\Test\Result;
/** @covers \JKingWeb\Arsse\Db\ResultAggregate<extended> */ /** @covers \JKingWeb\Arsse\Db\ResultAggregate<extended> */
class TestResultAggregate extends \JKingWeb\Arsse\Test\AbstractTest { class TestResultAggregate extends \JKingWeb\Arsse\Test\AbstractTest {
public function testGetChangeCountAndLastInsertId():void { public function testGetChangeCountAndLastInsertId(): void {
$in = [ $in = [
new Result([], 3, 4), new Result([], 3, 4),
new Result([], 27, 10), new Result([], 27, 10),
@ -18,7 +18,7 @@ class TestResultAggregate extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertEquals(2112, $r->lastId()); $this->assertEquals(2112, $r->lastId());
} }
public function testIterateOverResults():void { public function testIterateOverResults(): void {
$in = [ $in = [
new Result([['col' => 1]]), new Result([['col' => 1]]),
new Result([['col' => 2]]), new Result([['col' => 2]]),
@ -31,7 +31,7 @@ class TestResultAggregate extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertEquals([0 => 1, 1 => 2, 2 => 3], $rows); $this->assertEquals([0 => 1, 1 => 2, 2 => 3], $rows);
} }
public function testIterateOverResultsTwice():void { public function testIterateOverResultsTwice(): void {
$in = [ $in = [
new Result([['col' => 1]]), new Result([['col' => 1]]),
new Result([['col' => 2]]), new Result([['col' => 2]]),
@ -49,7 +49,7 @@ class TestResultAggregate extends \JKingWeb\Arsse\Test\AbstractTest {
} }
} }
public function testGetSingleValues():void { public function testGetSingleValues(): void {
$test = new ResultAggregate(...[ $test = new ResultAggregate(...[
new Result([['year' => 1867]]), new Result([['year' => 1867]]),
new Result([['year' => 1970]]), new Result([['year' => 1970]]),
@ -61,7 +61,7 @@ class TestResultAggregate extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame(null, $test->getValue()); $this->assertSame(null, $test->getValue());
} }
public function testGetFirstValuesOnly():void { public function testGetFirstValuesOnly(): void {
$test = new ResultAggregate(...[ $test = new ResultAggregate(...[
new Result([['year' => 1867, 'century' => 19]]), new Result([['year' => 1867, 'century' => 19]]),
new Result([['year' => 1970, 'century' => 20]]), new Result([['year' => 1970, 'century' => 20]]),
@ -73,7 +73,7 @@ class TestResultAggregate extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame(null, $test->getValue()); $this->assertSame(null, $test->getValue());
} }
public function testGetRows():void { public function testGetRows(): void {
$test = new ResultAggregate(...[ $test = new ResultAggregate(...[
new Result([['album' => '2112', 'track' => '2112']]), new Result([['album' => '2112', 'track' => '2112']]),
new Result([['album' => 'Clockwork Angels', 'track' => 'The Wreckers']]), new Result([['album' => 'Clockwork Angels', 'track' => 'The Wreckers']]),
@ -87,7 +87,7 @@ class TestResultAggregate extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame(null, $test->getRow()); $this->assertSame(null, $test->getRow());
} }
public function testGetAllRows():void { public function testGetAllRows(): void {
$test = new ResultAggregate(...[ $test = new ResultAggregate(...[
new Result([['album' => '2112', 'track' => '2112']]), new Result([['album' => '2112', 'track' => '2112']]),
new Result([['album' => 'Clockwork Angels', 'track' => 'The Wreckers']]), new Result([['album' => 'Clockwork Angels', 'track' => 'The Wreckers']]),

10
tests/cases/Db/TestResultEmpty.php

@ -6,13 +6,13 @@ use JKingWeb\Arsse\Db\ResultEmpty;
/** @covers \JKingWeb\Arsse\Db\ResultEmpty<extended> */ /** @covers \JKingWeb\Arsse\Db\ResultEmpty<extended> */
class TestResultEmpty extends \JKingWeb\Arsse\Test\AbstractTest { class TestResultEmpty extends \JKingWeb\Arsse\Test\AbstractTest {
public function testGetChangeCountAndLastInsertId():void { public function testGetChangeCountAndLastInsertId(): void {
$r = new ResultEmpty; $r = new ResultEmpty;
$this->assertEquals(0, $r->changes()); $this->assertEquals(0, $r->changes());
$this->assertEquals(0, $r->lastId()); $this->assertEquals(0, $r->lastId());
} }
public function testIterateOverResults():void { public function testIterateOverResults(): void {
$rows = []; $rows = [];
foreach (new ResultEmpty as $index => $row) { foreach (new ResultEmpty as $index => $row) {
$rows[$index] = $row['col']; $rows[$index] = $row['col'];
@ -20,17 +20,17 @@ class TestResultEmpty extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertEquals([], $rows); $this->assertEquals([], $rows);
} }
public function testGetSingleValues():void { public function testGetSingleValues(): void {
$test = new ResultEmpty; $test = new ResultEmpty;
$this->assertSame(null, $test->getValue()); $this->assertSame(null, $test->getValue());
} }
public function testGetRows():void { public function testGetRows(): void {
$test = new ResultEmpty; $test = new ResultEmpty;
$this->assertSame(null, $test->getRow()); $this->assertSame(null, $test->getRow());
} }
public function testGetAllRows():void { public function testGetAllRows(): void {
$test = new ResultEmpty; $test = new ResultEmpty;
$rows = []; $rows = [];
$this->assertEquals($rows, $test->getAll()); $this->assertEquals($rows, $test->getAll());

6
tests/cases/Db/TestTransaction.php

@ -23,7 +23,7 @@ class TestTransaction extends \JKingWeb\Arsse\Test\AbstractTest {
$this->drv = $drv; $this->drv = $drv;
} }
public function testManipulateTransactions():void { public function testManipulateTransactions(): void {
$tr1 = new Transaction($this->drv); $tr1 = new Transaction($this->drv);
$tr2 = new Transaction($this->drv); $tr2 = new Transaction($this->drv);
\Phake::verify($this->drv, \Phake::times(2))->savepointCreate; \Phake::verify($this->drv, \Phake::times(2))->savepointCreate;
@ -35,7 +35,7 @@ class TestTransaction extends \JKingWeb\Arsse\Test\AbstractTest {
\Phake::verify($this->drv)->savepointUndo(2); \Phake::verify($this->drv)->savepointUndo(2);
} }
public function testCloseTransactions():void { public function testCloseTransactions(): void {
$tr1 = new Transaction($this->drv); $tr1 = new Transaction($this->drv);
$tr2 = new Transaction($this->drv); $tr2 = new Transaction($this->drv);
$this->assertTrue($tr1->isPending()); $this->assertTrue($tr1->isPending());
@ -50,7 +50,7 @@ class TestTransaction extends \JKingWeb\Arsse\Test\AbstractTest {
\Phake::verify($this->drv)->savepointUndo(2); \Phake::verify($this->drv)->savepointUndo(2);
} }
public function testIgnoreRollbackErrors():void { public function testIgnoreRollbackErrors(): void {
\Phake::when($this->drv)->savepointUndo->thenThrow(new Exception("savepointStale")); \Phake::when($this->drv)->savepointUndo->thenThrow(new Exception("savepointStale"));
$tr1 = new Transaction($this->drv); $tr1 = new Transaction($this->drv);
$tr2 = new Transaction($this->drv); $tr2 = new Transaction($this->drv);

14
tests/cases/Exception/TestException.php

@ -28,7 +28,7 @@ class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
self::clearData(true); self::clearData(true);
} }
public function testBaseClass():void { public function testBaseClass(): void {
$this->assertException("unknown"); $this->assertException("unknown");
throw new Exception("unknown"); throw new Exception("unknown");
} }
@ -36,7 +36,7 @@ class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
/** /**
* @depends testBaseClass * @depends testBaseClass
*/ */
public function testBaseClassWithoutMessage():void { public function testBaseClassWithoutMessage(): void {
$this->assertException("unknown"); $this->assertException("unknown");
throw new Exception(); throw new Exception();
} }
@ -44,7 +44,7 @@ class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
/** /**
* @depends testBaseClass * @depends testBaseClass
*/ */
public function testDerivedClass():void { public function testDerivedClass(): void {
$this->assertException("fileMissing", "Lang"); $this->assertException("fileMissing", "Lang");
throw new LangException("fileMissing"); throw new LangException("fileMissing");
} }
@ -52,7 +52,7 @@ class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
/** /**
* @depends testDerivedClass * @depends testDerivedClass
*/ */
public function testDerivedClassWithMessageParameters():void { public function testDerivedClassWithMessageParameters(): void {
$this->assertException("fileMissing", "Lang"); $this->assertException("fileMissing", "Lang");
throw new LangException("fileMissing", "en"); throw new LangException("fileMissing", "en");
} }
@ -60,7 +60,7 @@ class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
/** /**
* @depends testBaseClass * @depends testBaseClass
*/ */
public function testBaseClassWithUnknownCode():void { public function testBaseClassWithUnknownCode(): void {
$this->assertException("uncoded"); $this->assertException("uncoded");
throw new Exception("testThisExceptionMessageDoesNotExist"); throw new Exception("testThisExceptionMessageDoesNotExist");
} }
@ -68,13 +68,13 @@ class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
/** /**
* @depends testBaseClassWithUnknownCode * @depends testBaseClassWithUnknownCode
*/ */
public function testDerivedClassWithMissingMessage():void { public function testDerivedClassWithMissingMessage(): void {
$this->assertException("uncoded"); $this->assertException("uncoded");
throw new LangException("testThisExceptionMessageDoesNotExist"); throw new LangException("testThisExceptionMessageDoesNotExist");
} }
/** @covers \JKingWeb\Arsse\ExceptionFatal */ /** @covers \JKingWeb\Arsse\ExceptionFatal */
public function testFatalException():void { public function testFatalException(): void {
$this->expectException('JKingWeb\Arsse\ExceptionFatal'); $this->expectException('JKingWeb\Arsse\ExceptionFatal');
throw new \JKingWeb\Arsse\ExceptionFatal(""); throw new \JKingWeb\Arsse\ExceptionFatal("");
} }

34
tests/cases/Feed/TestFeed.php

@ -98,7 +98,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
Arsse::$db = \Phake::mock(Database::class); Arsse::$db = \Phake::mock(Database::class);
} }
public function testParseAFeed():void { public function testParseAFeed(): void {
// test that various properties are set on the feed and on items // test that various properties are set on the feed and on items
$f = new Feed(null, $this->base."Parsing/Valid"); $f = new Feed(null, $this->base."Parsing/Valid");
$this->assertTrue(isset($f->lastModified)); $this->assertTrue(isset($f->lastModified));
@ -141,37 +141,37 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame($categories, $f->data->items[5]->categories); $this->assertSame($categories, $f->data->items[5]->categories);
} }
public function testDiscoverAFeedSuccessfully():void { public function testDiscoverAFeedSuccessfully(): void {
$this->assertSame($this->base."Discovery/Feed", Feed::discover($this->base."Discovery/Valid")); $this->assertSame($this->base."Discovery/Feed", Feed::discover($this->base."Discovery/Valid"));
$this->assertSame($this->base."Discovery/Feed", Feed::discover($this->base."Discovery/Feed")); $this->assertSame($this->base."Discovery/Feed", Feed::discover($this->base."Discovery/Feed"));
} }
public function testDiscoverAFeedUnsuccessfully():void { public function testDiscoverAFeedUnsuccessfully(): void {
$this->assertException("subscriptionNotFound", "Feed"); $this->assertException("subscriptionNotFound", "Feed");
Feed::discover($this->base."Discovery/Invalid"); Feed::discover($this->base."Discovery/Invalid");
} }
public function testParseEntityExpansionAttack():void { public function testParseEntityExpansionAttack(): void {
$this->assertException("xmlEntity", "Feed"); $this->assertException("xmlEntity", "Feed");
new Feed(null, $this->base."Parsing/XEEAttack"); new Feed(null, $this->base."Parsing/XEEAttack");
} }
public function testParseExternalEntityAttack():void { public function testParseExternalEntityAttack(): void {
$this->assertException("xmlEntity", "Feed"); $this->assertException("xmlEntity", "Feed");
new Feed(null, $this->base."Parsing/XXEAttack"); new Feed(null, $this->base."Parsing/XXEAttack");
} }
public function testParseAnUnsupportedFeed():void { public function testParseAnUnsupportedFeed(): void {
$this->assertException("unsupportedFeedFormat", "Feed"); $this->assertException("unsupportedFeedFormat", "Feed");
new Feed(null, $this->base."Parsing/Unsupported"); new Feed(null, $this->base."Parsing/Unsupported");
} }
public function testParseAMalformedFeed():void { public function testParseAMalformedFeed(): void {
$this->assertException("malformedXml", "Feed"); $this->assertException("malformedXml", "Feed");
new Feed(null, $this->base."Parsing/Malformed"); new Feed(null, $this->base."Parsing/Malformed");
} }
public function testDeduplicateFeedItems():void { public function testDeduplicateFeedItems(): void {
// duplicates with dates lead to the newest match being kept // duplicates with dates lead to the newest match being kept
$t = strtotime("2002-05-19T15:21:36Z"); $t = strtotime("2002-05-19T15:21:36Z");
$f = new Feed(null, $this->base."Deduplication/Permalink-Dates"); $f = new Feed(null, $this->base."Deduplication/Permalink-Dates");
@ -198,7 +198,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame("http://example.com/1", $f->newItems[0]->url); $this->assertSame("http://example.com/1", $f->newItems[0]->url);
} }
public function testHandleCacheHeadersOn304():void { public function testHandleCacheHeadersOn304(): void {
// upon 304, the client should re-use the caching header values it supplied the server // upon 304, the client should re-use the caching header values it supplied the server
$t = time(); $t = time();
$e = "78567a"; $e = "78567a";
@ -216,7 +216,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame($e, $f->resource->getETag()); $this->assertSame($e, $f->resource->getETag());
} }
public function testHandleCacheHeadersOn200():void { public function testHandleCacheHeadersOn200(): void {
// these tests should trust the server-returned time, even in cases of obviously incorrect results // these tests should trust the server-returned time, even in cases of obviously incorrect results
$t = time() - 2000; $t = time() - 2000;
$f = new Feed(null, $this->base."Caching/200Past"); $f = new Feed(null, $this->base."Caching/200Past");
@ -244,7 +244,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertTime($t, $f->lastModified); $this->assertTime($t, $f->lastModified);
} }
public function testComputeNextFetchOnError():void { public function testComputeNextFetchOnError(): void {
for ($a = 0; $a < 100; $a++) { for ($a = 0; $a < 100; $a++) {
if ($a < 3) { if ($a < 3) {
$this->assertTime("now + 5 minutes", Feed::nextFetchOnError($a)); $this->assertTime("now + 5 minutes", Feed::nextFetchOnError($a));
@ -257,7 +257,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provide304Timestamps */ /** @dataProvider provide304Timestamps */
public function testComputeNextFetchFrom304(string $t, string $exp):void { public function testComputeNextFetchFrom304(string $t, string $exp): void {
$t = $t ? strtotime($t) : ""; $t = $t ? strtotime($t) : "";
$f = new Feed(null, $this->base."NextFetch/NotModified?t=$t", Date::transform($t, "http")); $f = new Feed(null, $this->base."NextFetch/NotModified?t=$t", Date::transform($t, "http"));
$exp = strtotime($exp); $exp = strtotime($exp);
@ -279,13 +279,13 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
]; ];
} }
public function testComputeNextFetchFrom304WithoutDate():void { public function testComputeNextFetchFrom304WithoutDate(): void {
$f = new Feed(null, $this->base."NextFetch/NotModifiedEtag"); $f = new Feed(null, $this->base."NextFetch/NotModifiedEtag");
$exp = strtotime("now + 3 hours"); $exp = strtotime("now + 3 hours");
$this->assertTime($exp, $f->nextFetch); $this->assertTime($exp, $f->nextFetch);
} }
public function testComputeNextFetchFrom200():void { public function testComputeNextFetchFrom200(): void {
// if less than half an hour, check in 15 minutes // if less than half an hour, check in 15 minutes
$f = new Feed(null, $this->base."NextFetch/30m"); $f = new Feed(null, $this->base."NextFetch/30m");
$exp = strtotime("now + 15 minutes"); $exp = strtotime("now + 15 minutes");
@ -312,7 +312,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertTime($exp, $f->nextFetch); $this->assertTime($exp, $f->nextFetch);
} }
public function testMatchLatestArticles():void { public function testMatchLatestArticles(): void {
\Phake::when(Arsse::$db)->feedMatchLatest(1, $this->anything())->thenReturn(new Result($this->latest)); \Phake::when(Arsse::$db)->feedMatchLatest(1, $this->anything())->thenReturn(new Result($this->latest));
$f = new Feed(1, $this->base."Matching/1"); $f = new Feed(1, $this->base."Matching/1");
$this->assertCount(0, $f->newItems); $this->assertCount(0, $f->newItems);
@ -328,7 +328,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertCount(2, $f->changedItems); $this->assertCount(2, $f->changedItems);
} }
public function testMatchHistoricalArticles():void { public function testMatchHistoricalArticles(): void {
\Phake::when(Arsse::$db)->feedMatchLatest(1, $this->anything())->thenReturn(new Result($this->latest)); \Phake::when(Arsse::$db)->feedMatchLatest(1, $this->anything())->thenReturn(new Result($this->latest));
\Phake::when(Arsse::$db)->feedMatchIds(1, $this->anything(), $this->anything(), $this->anything(), $this->anything())->thenReturn(new Result($this->others)); \Phake::when(Arsse::$db)->feedMatchIds(1, $this->anything(), $this->anything(), $this->anything(), $this->anything())->thenReturn(new Result($this->others));
$f = new Feed(1, $this->base."Matching/5"); $f = new Feed(1, $this->base."Matching/5");
@ -336,7 +336,7 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertCount(0, $f->changedItems); $this->assertCount(0, $f->changedItems);
} }
public function testScrapeFullContent():void { public function testScrapeFullContent(): void {
// first make sure that the absence of scraping works as expected // first make sure that the absence of scraping works as expected
$f = new Feed(null, $this->base."Scraping/Feed"); $f = new Feed(null, $this->base."Scraping/Feed");
$exp = "<p>Partial content</p>"; $exp = "<p>Partial content</p>";

18
tests/cases/Feed/TestFetching.php

@ -27,48 +27,48 @@ class TestFetching extends \JKingWeb\Arsse\Test\AbstractTest {
self::setConf(); self::setConf();
} }
public function testHandle400():void { public function testHandle400(): void {
$this->assertException("unsupportedFeedFormat", "Feed"); $this->assertException("unsupportedFeedFormat", "Feed");
new Feed(null, $this->base."Fetching/Error?code=400"); new Feed(null, $this->base."Fetching/Error?code=400");
} }
public function testHandle401():void { public function testHandle401(): void {
$this->assertException("unauthorized", "Feed"); $this->assertException("unauthorized", "Feed");
new Feed(null, $this->base."Fetching/Error?code=401"); new Feed(null, $this->base."Fetching/Error?code=401");
} }
public function testHandle403():void { public function testHandle403(): void {
$this->assertException("forbidden", "Feed"); $this->assertException("forbidden", "Feed");
new Feed(null, $this->base."Fetching/Error?code=403"); new Feed(null, $this->base."Fetching/Error?code=403");
} }
public function testHandle404():void { public function testHandle404(): void {
$this->assertException("invalidUrl", "Feed"); $this->assertException("invalidUrl", "Feed");
new Feed(null, $this->base."Fetching/Error?code=404"); new Feed(null, $this->base."Fetching/Error?code=404");
} }
public function testHandle500():void { public function testHandle500(): void {
$this->assertException("unsupportedFeedFormat", "Feed"); $this->assertException("unsupportedFeedFormat", "Feed");
new Feed(null, $this->base."Fetching/Error?code=500"); new Feed(null, $this->base."Fetching/Error?code=500");
} }
public function testHandleARedirectLoop():void { public function testHandleARedirectLoop(): void {
$this->assertException("maxRedirect", "Feed"); $this->assertException("maxRedirect", "Feed");
new Feed(null, $this->base."Fetching/EndlessLoop?i=0"); new Feed(null, $this->base."Fetching/EndlessLoop?i=0");
} }
public function testHandleAnOverlyLargeFeed():void { public function testHandleAnOverlyLargeFeed(): void {
Arsse::$conf->fetchSizeLimit = 512; Arsse::$conf->fetchSizeLimit = 512;
$this->assertException("maxSize", "Feed"); $this->assertException("maxSize", "Feed");
new Feed(null, $this->base."Fetching/TooLarge"); new Feed(null, $this->base."Fetching/TooLarge");
} }
public function testHandleACertificateError():void { public function testHandleACertificateError(): void {
$this->assertException("invalidCertificate", "Feed"); $this->assertException("invalidCertificate", "Feed");
new Feed(null, "https://localhost:8000/"); new Feed(null, "https://localhost:8000/");
} }
public function testHandleATimeout():void { public function testHandleATimeout(): void {
Arsse::$conf->fetchTimeout = 1; Arsse::$conf->fetchTimeout = 1;
$this->assertException("timeout", "Feed"); $this->assertException("timeout", "Feed");
new Feed(null, $this->base."Fetching/Timeout"); new Feed(null, $this->base."Fetching/Timeout");

4
tests/cases/ImportExport/TestFile.php

@ -45,7 +45,7 @@ class TestFile extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideFileExports */ /** @dataProvider provideFileExports */
public function testExportToAFile(string $file, string $user, bool $flat, $exp):void { public function testExportToAFile(string $file, string $user, bool $flat, $exp): void {
$path = $this->path.$file; $path = $this->path.$file;
try { try {
if ($exp instanceof \JKingWeb\Arsse\AbstractException) { if ($exp instanceof \JKingWeb\Arsse\AbstractException) {
@ -84,7 +84,7 @@ class TestFile extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideFileImports */ /** @dataProvider provideFileImports */
public function testImportFromAFile(string $file, string $user, bool $flat, bool $replace, $exp):void { public function testImportFromAFile(string $file, string $user, bool $flat, bool $replace, $exp): void {
$path = $this->path.$file; $path = $this->path.$file;
try { try {
if ($exp instanceof \JKingWeb\Arsse\AbstractException) { if ($exp instanceof \JKingWeb\Arsse\AbstractException) {

16
tests/cases/ImportExport/TestImportExport.php

@ -146,13 +146,13 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
self::clearData(); self::clearData();
} }
public function testImportForAMissingUser():void { public function testImportForAMissingUser(): void {
\Phake::when(Arsse::$user)->exists->thenReturn(false); \Phake::when(Arsse::$user)->exists->thenReturn(false);
$this->assertException("doesNotExist", "User"); $this->assertException("doesNotExist", "User");
$this->proc->import("john.doe@example.com", "", false, false); $this->proc->import("john.doe@example.com", "", false, false);
} }
public function testImportWithInvalidFolder():void { public function testImportWithInvalidFolder(): void {
$in = [[ $in = [[
], [1 => ], [1 =>
['id' => 1, 'name' => "", 'parent' => 0], ['id' => 1, 'name' => "", 'parent' => 0],
@ -162,7 +162,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
$this->proc->import("john.doe@example.com", "", false, false); $this->proc->import("john.doe@example.com", "", false, false);
} }
public function testImportWithDuplicateFolder():void { public function testImportWithDuplicateFolder(): void {
$in = [[ $in = [[
], [1 => ], [1 =>
['id' => 1, 'name' => "New", 'parent' => 0], ['id' => 1, 'name' => "New", 'parent' => 0],
@ -173,7 +173,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
$this->proc->import("john.doe@example.com", "", false, false); $this->proc->import("john.doe@example.com", "", false, false);
} }
public function testMakeNoEffectiveChanges():void { public function testMakeNoEffectiveChanges(): void {
$in = [[ $in = [[
['url' => "http://localhost:8000/Import/nasa-jpl", 'title' => "NASA JPL", 'folder' => 3, 'tags' => ["tech"]], ['url' => "http://localhost:8000/Import/nasa-jpl", 'title' => "NASA JPL", 'folder' => 3, 'tags' => ["tech"]],
['url' => "http://localhost:8000/Import/ars", 'title' => "Ars Technica", 'folder' => 2, 'tags' => ["frequent", "tech"]], ['url' => "http://localhost:8000/Import/ars", 'title' => "Ars Technica", 'folder' => 2, 'tags' => ["frequent", "tech"]],
@ -197,7 +197,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
$this->compareExpectations($this->drv, $exp); $this->compareExpectations($this->drv, $exp);
} }
public function testModifyASubscription():void { public function testModifyASubscription(): void {
$in = [[ $in = [[
['url' => "http://localhost:8000/Import/nasa-jpl", 'title' => "NASA JPL", 'folder' => 3, 'tags' => ["tech"]], ['url' => "http://localhost:8000/Import/nasa-jpl", 'title' => "NASA JPL", 'folder' => 3, 'tags' => ["tech"]],
['url' => "http://localhost:8000/Import/ars", 'title' => "Ars Technica", 'folder' => 2, 'tags' => ["frequent", "tech"]], ['url' => "http://localhost:8000/Import/ars", 'title' => "Ars Technica", 'folder' => 2, 'tags' => ["frequent", "tech"]],
@ -222,7 +222,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
$this->compareExpectations($this->drv, $exp); $this->compareExpectations($this->drv, $exp);
} }
public function testImportAFeed():void { public function testImportAFeed(): void {
$in = [[ $in = [[
['url' => "http://localhost:8000/Import/some-feed", 'title' => "Some Feed", 'folder' => 0, 'tags' => ["frequent", "cryptic"]], //one existing tag and one new one ['url' => "http://localhost:8000/Import/some-feed", 'title' => "Some Feed", 'folder' => 0, 'tags' => ["frequent", "cryptic"]], //one existing tag and one new one
], []]; ], []];
@ -237,7 +237,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
$this->compareExpectations($this->drv, $exp); $this->compareExpectations($this->drv, $exp);
} }
public function testImportAFeedWithAnInvalidTag():void { public function testImportAFeedWithAnInvalidTag(): void {
$in = [[ $in = [[
['url' => "http://localhost:8000/Import/some-feed", 'title' => "Some Feed", 'folder' => 0, 'tags' => [""]], ['url' => "http://localhost:8000/Import/some-feed", 'title' => "Some Feed", 'folder' => 0, 'tags' => [""]],
], []]; ], []];
@ -246,7 +246,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
$this->proc->import("john.doe@example.com", "", false, false); $this->proc->import("john.doe@example.com", "", false, false);
} }
public function testReplaceData():void { public function testReplaceData(): void {
$in = [[ $in = [[
['url' => "http://localhost:8000/Import/some-feed", 'title' => "Some Feed", 'folder' => 1, 'tags' => ["frequent", "cryptic"]], ['url' => "http://localhost:8000/Import/some-feed", 'title' => "Some Feed", 'folder' => 1, 'tags' => ["frequent", "cryptic"]],
], [1 => ], [1 =>

8
tests/cases/ImportExport/TestOPML.php

@ -86,28 +86,28 @@ OPML_EXPORT_SERIALIZATION;
\Phake::when(Arsse::$user)->exists->thenReturn(true); \Phake::when(Arsse::$user)->exists->thenReturn(true);
} }
public function testExportToOpml():void { public function testExportToOpml(): void {
\Phake::when(Arsse::$db)->folderList("john.doe@example.com")->thenReturn(new Result($this->folders)); \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)->subscriptionList("john.doe@example.com")->thenReturn(new Result($this->subscriptions));
\Phake::when(Arsse::$db)->tagSummarize("john.doe@example.com")->thenReturn(new Result($this->tags)); \Phake::when(Arsse::$db)->tagSummarize("john.doe@example.com")->thenReturn(new Result($this->tags));
$this->assertXmlStringEqualsXmlString($this->serialization, (new OPML)->export("john.doe@example.com")); $this->assertXmlStringEqualsXmlString($this->serialization, (new OPML)->export("john.doe@example.com"));
} }
public function testExportToFlatOpml():void { public function testExportToFlatOpml(): void {
\Phake::when(Arsse::$db)->folderList("john.doe@example.com")->thenReturn(new Result($this->folders)); \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)->subscriptionList("john.doe@example.com")->thenReturn(new Result($this->subscriptions));
\Phake::when(Arsse::$db)->tagSummarize("john.doe@example.com")->thenReturn(new Result($this->tags)); \Phake::when(Arsse::$db)->tagSummarize("john.doe@example.com")->thenReturn(new Result($this->tags));
$this->assertXmlStringEqualsXmlString($this->serializationFlat, (new OPML)->export("john.doe@example.com", true)); $this->assertXmlStringEqualsXmlString($this->serializationFlat, (new OPML)->export("john.doe@example.com", true));
} }
public function testExportToOpmlAMissingUser():void { public function testExportToOpmlAMissingUser(): void {
\Phake::when(Arsse::$user)->exists->thenReturn(false); \Phake::when(Arsse::$user)->exists->thenReturn(false);
$this->assertException("doesNotExist", "User"); $this->assertException("doesNotExist", "User");
(new OPML)->export("john.doe@example.com"); (new OPML)->export("john.doe@example.com");
} }
/** @dataProvider provideParserData */ /** @dataProvider provideParserData */
public function testParseOpmlForImport(string $file, bool $flat, $exp):void { public function testParseOpmlForImport(string $file, bool $flat, $exp): void {
$data = file_get_contents(\JKingWeb\Arsse\DOCROOT."Import/OPML/$file"); $data = file_get_contents(\JKingWeb\Arsse\DOCROOT."Import/OPML/$file");
// set up a partial mock to make the ImportExport::parse() method visible // set up a partial mock to make the ImportExport::parse() method visible
$parser = \Phake::makeVisible(\Phake::partialMock(OPML::class)); $parser = \Phake::makeVisible(\Phake::partialMock(OPML::class));

10
tests/cases/Lang/TestBasic.php

@ -16,14 +16,14 @@ class TestBasic extends \JKingWeb\Arsse\Test\AbstractTest {
public $path; public $path;
public $l; public $l;
public function testListLanguages():void { public function testListLanguages(): void {
$this->assertCount(sizeof($this->files), $this->l->list("en")); $this->assertCount(sizeof($this->files), $this->l->list("en"));
} }
/** /**
* @depends testListLanguages * @depends testListLanguages
*/ */
public function testSetLanguage():void { public function testSetLanguage(): void {
$this->assertEquals("en", $this->l->set("en")); $this->assertEquals("en", $this->l->set("en"));
$this->assertEquals("en_ca", $this->l->set("en_ca")); $this->assertEquals("en_ca", $this->l->set("en_ca"));
$this->assertEquals("de", $this->l->set("de_ch")); $this->assertEquals("de", $this->l->set("de_ch"));
@ -36,7 +36,7 @@ class TestBasic extends \JKingWeb\Arsse\Test\AbstractTest {
/** /**
* @depends testSetLanguage * @depends testSetLanguage
*/ */
public function testLoadInternalStrings():void { public function testLoadInternalStrings(): void {
$this->assertEquals("", $this->l->set("", true)); $this->assertEquals("", $this->l->set("", true));
$this->assertCount(sizeof(TestClass::REQUIRED), $this->l->dump()); $this->assertCount(sizeof(TestClass::REQUIRED), $this->l->dump());
} }
@ -44,7 +44,7 @@ class TestBasic extends \JKingWeb\Arsse\Test\AbstractTest {
/** /**
* @depends testLoadInternalStrings * @depends testLoadInternalStrings
*/ */
public function testLoadDefaultLanguage():void { public function testLoadDefaultLanguage(): void {
$this->assertEquals(TestClass::DEFAULT, $this->l->set(TestClass::DEFAULT, true)); $this->assertEquals(TestClass::DEFAULT, $this->l->set(TestClass::DEFAULT, true));
$str = $this->l->dump(); $str = $this->l->dump();
$this->assertArrayHasKey('Exception.JKingWeb/Arsse/Exception.uncoded', $str); $this->assertArrayHasKey('Exception.JKingWeb/Arsse/Exception.uncoded', $str);
@ -54,7 +54,7 @@ class TestBasic extends \JKingWeb\Arsse\Test\AbstractTest {
/** /**
* @depends testLoadDefaultLanguage * @depends testLoadDefaultLanguage
*/ */
public function testLoadSupplementaryLanguage():void { public function testLoadSupplementaryLanguage(): void {
$this->l->set(TestClass::DEFAULT, true); $this->l->set(TestClass::DEFAULT, true);
$this->assertEquals("ja", $this->l->set("ja", true)); $this->assertEquals("ja", $this->l->set("ja", true));
$str = $this->l->dump(); $str = $this->l->dump();

24
tests/cases/Lang/TestComplex.php

@ -16,11 +16,11 @@ class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {
public $path; public $path;
public $l; public $l;
public function setUpSeries():void { public function setUpSeries(): void {
$this->l->set(TestClass::DEFAULT, true); $this->l->set(TestClass::DEFAULT, true);
} }
public function testLazyLoad():void { public function testLazyLoad(): void {
$this->l->set("ja"); $this->l->set("ja");
$this->assertArrayNotHasKey('Test.absentText', $this->l->dump()); $this->assertArrayNotHasKey('Test.absentText', $this->l->dump());
} }
@ -28,14 +28,14 @@ class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {
/** /**
* @depends testLazyLoad * @depends testLazyLoad
*/ */
public function testGetWantedAndLoadedLocale():void { public function testGetWantedAndLoadedLocale(): void {
$this->l->set("en", true); $this->l->set("en", true);
$this->l->set("ja"); $this->l->set("ja");
$this->assertEquals("ja", $this->l->get()); $this->assertEquals("ja", $this->l->get());
$this->assertEquals("en", $this->l->get(true)); $this->assertEquals("en", $this->l->get(true));
} }
public function testLoadCascadeOfFiles():void { public function testLoadCascadeOfFiles(): void {
$this->l->set("ja", true); $this->l->set("ja", true);
$this->assertEquals("de", $this->l->set("de", true)); $this->assertEquals("de", $this->l->set("de", true));
$str = $this->l->dump(); $str = $this->l->dump();
@ -46,11 +46,11 @@ class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {
/** /**
* @depends testLoadCascadeOfFiles * @depends testLoadCascadeOfFiles
*/ */
public function testLoadSubtag():void { public function testLoadSubtag(): void {
$this->assertEquals("en_ca", $this->l->set("en_ca", true)); $this->assertEquals("en_ca", $this->l->set("en_ca", true));
} }
public function testFetchAMessage():void { public function testFetchAMessage(): void {
$this->l->set("de"); $this->l->set("de");
$this->assertEquals('und der Stein der Weisen', $this->l->msg('Test.presentText')); $this->assertEquals('und der Stein der Weisen', $this->l->msg('Test.presentText'));
} }
@ -58,7 +58,7 @@ class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {
/** /**
* @depends testFetchAMessage * @depends testFetchAMessage
*/ */
public function testFetchAMessageWithMissingParameters():void { public function testFetchAMessageWithMissingParameters(): void {
$this->l->set("en_ca", true); $this->l->set("en_ca", true);
$this->assertEquals('{0} and {1}', $this->l->msg('Test.presentText')); $this->assertEquals('{0} and {1}', $this->l->msg('Test.presentText'));
} }
@ -66,7 +66,7 @@ class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {
/** /**
* @depends testFetchAMessage * @depends testFetchAMessage
*/ */
public function testFetchAMessageWithSingleNumericParameter():void { public function testFetchAMessageWithSingleNumericParameter(): void {
$this->l->set("en_ca", true); $this->l->set("en_ca", true);
$this->assertEquals('Default language file "en" missing', $this->l->msg('Exception.JKingWeb/Arsse/Lang/Exception.defaultFileMissing', TestClass::DEFAULT)); $this->assertEquals('Default language file "en" missing', $this->l->msg('Exception.JKingWeb/Arsse/Lang/Exception.defaultFileMissing', TestClass::DEFAULT));
} }
@ -74,7 +74,7 @@ class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {
/** /**
* @depends testFetchAMessage * @depends testFetchAMessage
*/ */
public function testFetchAMessageWithMultipleNumericParameters():void { public function testFetchAMessageWithMultipleNumericParameters(): void {
$this->l->set("en_ca", true); $this->l->set("en_ca", true);
$this->assertEquals('Happy Rotter and the Philosopher\'s Stone', $this->l->msg('Test.presentText', ['Happy Rotter', 'the Philosopher\'s Stone'])); $this->assertEquals('Happy Rotter and the Philosopher\'s Stone', $this->l->msg('Test.presentText', ['Happy Rotter', 'the Philosopher\'s Stone']));
} }
@ -82,14 +82,14 @@ class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {
/** /**
* @depends testFetchAMessage * @depends testFetchAMessage
*/ */
public function testFetchAMessageWithNamedParameters():void { public function testFetchAMessageWithNamedParameters(): void {
$this->assertEquals('Message string "Test.absentText" missing from all loaded language files (en)', $this->l->msg('Exception.JKingWeb/Arsse/Lang/Exception.stringMissing', ['msgID' => 'Test.absentText', 'fileList' => 'en'])); $this->assertEquals('Message string "Test.absentText" missing from all loaded language files (en)', $this->l->msg('Exception.JKingWeb/Arsse/Lang/Exception.stringMissing', ['msgID' => 'Test.absentText', 'fileList' => 'en']));
} }
/** /**
* @depends testFetchAMessage * @depends testFetchAMessage
*/ */
public function testReloadDefaultStrings():void { public function testReloadDefaultStrings(): void {
$this->l->set("de", true); $this->l->set("de", true);
$this->l->set("en", true); $this->l->set("en", true);
$this->assertEquals('and the Philosopher\'s Stone', $this->l->msg('Test.presentText')); $this->assertEquals('and the Philosopher\'s Stone', $this->l->msg('Test.presentText'));
@ -98,7 +98,7 @@ class TestComplex extends \JKingWeb\Arsse\Test\AbstractTest {
/** /**
* @depends testFetchAMessage * @depends testFetchAMessage
*/ */
public function testReloadGeneralTagAfterSubtag():void { public function testReloadGeneralTagAfterSubtag(): void {
$this->l->set("en", true); $this->l->set("en", true);
$this->l->set("en_us", true); $this->l->set("en_us", true);
$this->assertEquals('and the Sorcerer\'s Stone', $this->l->msg('Test.presentText')); $this->assertEquals('and the Sorcerer\'s Stone', $this->l->msg('Test.presentText'));

24
tests/cases/Lang/TestErrors.php

@ -16,65 +16,65 @@ class TestErrors extends \JKingWeb\Arsse\Test\AbstractTest {
public $path; public $path;
public $l; public $l;
public function setUpSeries():void { public function setUpSeries(): void {
$this->l->set("", true); $this->l->set("", true);
} }
public function testLoadEmptyFile():void { public function testLoadEmptyFile(): void {
$this->assertException("fileCorrupt", "Lang"); $this->assertException("fileCorrupt", "Lang");
$this->l->set("fr_ca", true); $this->l->set("fr_ca", true);
} }
public function testLoadFileWhichDoesNotReturnAnArray():void { public function testLoadFileWhichDoesNotReturnAnArray(): void {
$this->assertException("fileCorrupt", "Lang"); $this->assertException("fileCorrupt", "Lang");
$this->l->set("it", true); $this->l->set("it", true);
} }
public function testLoadFileWhichIsNotPhp():void { public function testLoadFileWhichIsNotPhp(): void {
$this->assertException("fileCorrupt", "Lang"); $this->assertException("fileCorrupt", "Lang");
$this->l->set("ko", true); $this->l->set("ko", true);
} }
public function testLoadFileWhichIsCorrupt():void { public function testLoadFileWhichIsCorrupt(): void {
$this->assertException("fileCorrupt", "Lang"); $this->assertException("fileCorrupt", "Lang");
$this->l->set("zh", true); $this->l->set("zh", true);
} }
public function testLoadFileWithooutReadPermission():void { public function testLoadFileWithooutReadPermission(): void {
$this->assertException("fileUnreadable", "Lang"); $this->assertException("fileUnreadable", "Lang");
$this->l->set("ru", true); $this->l->set("ru", true);
} }
public function testLoadSubtagOfMissingLanguage():void { public function testLoadSubtagOfMissingLanguage(): void {
$this->assertException("fileMissing", "Lang"); $this->assertException("fileMissing", "Lang");
$this->l->set("pt_br", true); $this->l->set("pt_br", true);
} }
public function testFetchInvalidMessage():void { public function testFetchInvalidMessage(): void {
$this->assertException("stringInvalid", "Lang"); $this->assertException("stringInvalid", "Lang");
$this->l->set("vi", true); $this->l->set("vi", true);
$txt = $this->l->msg('Test.presentText'); $txt = $this->l->msg('Test.presentText');
} }
public function testFetchMissingMessage():void { public function testFetchMissingMessage(): void {
$this->assertException("stringMissing", "Lang"); $this->assertException("stringMissing", "Lang");
$txt = $this->l->msg('Test.absentText'); $txt = $this->l->msg('Test.absentText');
} }
public function testLoadMissingDefaultLanguage():void { public function testLoadMissingDefaultLanguage(): void {
unlink($this->path.TestClass::DEFAULT.".php"); unlink($this->path.TestClass::DEFAULT.".php");
$this->assertException("defaultFileMissing", "Lang"); $this->assertException("defaultFileMissing", "Lang");
$this->l->set("fr", true); $this->l->set("fr", true);
} }
public function testLoadMissingLanguageWhenFetching():void { public function testLoadMissingLanguageWhenFetching(): void {
$this->l->set("en_ca"); $this->l->set("en_ca");
unlink($this->path.TestClass::DEFAULT.".php"); unlink($this->path.TestClass::DEFAULT.".php");
$this->assertException("fileMissing", "Lang"); $this->assertException("fileMissing", "Lang");
$this->l->msg('Test.presentText'); $this->l->msg('Test.presentText');
} }
public function testLoadMissingDefaultLanguageWhenFetching():void { public function testLoadMissingDefaultLanguageWhenFetching(): void {
unlink($this->path.TestClass::DEFAULT.".php"); unlink($this->path.TestClass::DEFAULT.".php");
$this->l = new TestClass($this->path); $this->l = new TestClass($this->path);
$this->assertException("stringMissing", "Lang"); $this->assertException("stringMissing", "Lang");

12
tests/cases/Misc/TestContext.php

@ -11,7 +11,7 @@ use JKingWeb\Arsse\Misc\ValueInfo;
/** @covers \JKingWeb\Arsse\Context\Context<extended> */ /** @covers \JKingWeb\Arsse\Context\Context<extended> */
class TestContext extends \JKingWeb\Arsse\Test\AbstractTest { class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
public function testVerifyInitialState():void { public function testVerifyInitialState(): void {
$c = new Context; $c = new Context;
foreach ((new \ReflectionObject($c))->getMethods(\ReflectionMethod::IS_PUBLIC) as $m) { foreach ((new \ReflectionObject($c))->getMethods(\ReflectionMethod::IS_PUBLIC) as $m) {
if ($m->isStatic() || strpos($m->name, "__") === 0) { if ($m->isStatic() || strpos($m->name, "__") === 0) {
@ -23,7 +23,7 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
} }
} }
public function testSetContextOptions():void { public function testSetContextOptions(): void {
$v = [ $v = [
'reverse' => true, 'reverse' => true,
'limit' => 10, 'limit' => 10,
@ -85,7 +85,7 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
} }
} }
public function testCleanIdArrayValues():void { public function testCleanIdArrayValues(): void {
$methods = ["articles", "editions", "tags", "labels", "subscriptions"]; $methods = ["articles", "editions", "tags", "labels", "subscriptions"];
$in = [1, "2", 3.5, 4.0, 4, "ook", 0, -20, true, false, null, new \DateTime(), -1.0]; $in = [1, "2", 3.5, 4.0, 4, "ook", 0, -20, true, false, null, new \DateTime(), -1.0];
$out = [1, 2, 4]; $out = [1, 2, 4];
@ -95,7 +95,7 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
} }
} }
public function testCleanFolderIdArrayValues():void { public function testCleanFolderIdArrayValues(): void {
$methods = ["folders", "foldersShallow"]; $methods = ["folders", "foldersShallow"];
$in = [1, "2", 3.5, 4.0, 4, "ook", 0, -20, true, false, null, new \DateTime(), -1.0]; $in = [1, "2", 3.5, 4.0, 4, "ook", 0, -20, true, false, null, new \DateTime(), -1.0];
$out = [1, 2, 4, 0]; $out = [1, 2, 4, 0];
@ -105,7 +105,7 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
} }
} }
public function testCleanStringArrayValues():void { public function testCleanStringArrayValues(): void {
$methods = ["searchTerms", "annotationTerms", "titleTerms", "authorTerms", "tagNames", "labelNames"]; $methods = ["searchTerms", "annotationTerms", "titleTerms", "authorTerms", "tagNames", "labelNames"];
$now = new \DateTime; $now = new \DateTime;
$in = [1, 3.0, "ook", 0, true, false, null, $now, ""]; $in = [1, 3.0, "ook", 0, true, false, null, $now, ""];
@ -116,7 +116,7 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
} }
} }
public function testCloneAContext():void { public function testCloneAContext(): void {
$c1 = new Context; $c1 = new Context;
$c2 = clone $c1; $c2 = clone $c1;
$this->assertEquals($c1, $c2); $this->assertEquals($c1, $c2);

8
tests/cases/Misc/TestDate.php

@ -14,7 +14,7 @@ class TestDate extends \JKingWeb\Arsse\Test\AbstractTest {
self::clearData(); self::clearData();
} }
public function testNormalizeADate():void { public function testNormalizeADate(): void {
$exp = new \DateTimeImmutable("2018-01-01T00:00:00Z"); $exp = new \DateTimeImmutable("2018-01-01T00:00:00Z");
$this->assertEquals($exp, Date::normalize(1514764800)); $this->assertEquals($exp, Date::normalize(1514764800));
$this->assertEquals($exp, Date::normalize("2018-01-01T00:00:00")); $this->assertEquals($exp, Date::normalize("2018-01-01T00:00:00"));
@ -26,7 +26,7 @@ class TestDate extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertNull(Date::normalize("2018-01-01T00:00:00Z", "http")); $this->assertNull(Date::normalize("2018-01-01T00:00:00Z", "http"));
} }
public function testFormatADate():void { public function testFormatADate(): void {
$test = new \DateTimeImmutable("2018-01-01T00:00:00Z"); $test = new \DateTimeImmutable("2018-01-01T00:00:00Z");
$this->assertNull(Date::transform(null, "http")); $this->assertNull(Date::transform(null, "http"));
$this->assertNull(Date::transform("ook", "http")); $this->assertNull(Date::transform("ook", "http"));
@ -40,7 +40,7 @@ class TestDate extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame(1514764800.265579, Date::transform("2018-01-01T00:00:00.265579Z", "float", "iso8601m")); $this->assertSame(1514764800.265579, Date::transform("2018-01-01T00:00:00.265579Z", "float", "iso8601m"));
} }
public function testMoveDateForward():void { public function testMoveDateForward(): void {
$test = new \DateTimeImmutable("2018-01-01T00:00:00Z"); $test = new \DateTimeImmutable("2018-01-01T00:00:00Z");
$this->assertNull(Date::add("P1D", null)); $this->assertNull(Date::add("P1D", null));
$this->assertNull(Date::add("P1D", "ook")); $this->assertNull(Date::add("P1D", "ook"));
@ -49,7 +49,7 @@ class TestDate extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertNull(Date::add("ook", $test)); $this->assertNull(Date::add("ook", $test));
} }
public function testMoveDateBack():void { public function testMoveDateBack(): void {
$test = new \DateTimeImmutable("2018-01-01T00:00:00Z"); $test = new \DateTimeImmutable("2018-01-01T00:00:00Z");
$this->assertNull(Date::sub("P1D", null)); $this->assertNull(Date::sub("P1D", null));
$this->assertNull(Date::sub("P1D", "ook")); $this->assertNull(Date::sub("P1D", "ook"));

2
tests/cases/Misc/TestHTTP.php

@ -12,7 +12,7 @@ use Psr\Http\Message\ResponseInterface;
/** @covers \JKingWeb\Arsse\Misc\HTTP */ /** @covers \JKingWeb\Arsse\Misc\HTTP */
class TestHTTP extends \JKingWeb\Arsse\Test\AbstractTest { class TestHTTP extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideMediaTypes */ /** @dataProvider provideMediaTypes */
public function testMatchMediaType(string $header, array $types, bool $exp):void { public function testMatchMediaType(string $header, array $types, bool $exp): void {
$msg = (new \Laminas\Diactoros\Request)->withHeader("Content-Type", $header); $msg = (new \Laminas\Diactoros\Request)->withHeader("Content-Type", $header);
$this->assertSame($exp, HTTP::matchType($msg, ...$types)); $this->assertSame($exp, HTTP::matchType($msg, ...$types));
$msg = (new \Laminas\Diactoros\Response)->withHeader("Content-Type", $header); $msg = (new \Laminas\Diactoros\Response)->withHeader("Content-Type", $header);

16
tests/cases/Misc/TestQuery.php

@ -11,14 +11,14 @@ use JKingWeb\Arsse\Misc\ValueInfo;
/** @covers \JKingWeb\Arsse\Misc\Query */ /** @covers \JKingWeb\Arsse\Misc\Query */
class TestQuery extends \JKingWeb\Arsse\Test\AbstractTest { class TestQuery extends \JKingWeb\Arsse\Test\AbstractTest {
public function testBasicQuery():void { public function testBasicQuery(): void {
$q = new Query("select * from table where a = ?", "int", 3); $q = new Query("select * from table where a = ?", "int", 3);
$this->assertSame("select * from table where a = ?", $q->getQuery()); $this->assertSame("select * from table where a = ?", $q->getQuery());
$this->assertSame(["int"], $q->getTypes()); $this->assertSame(["int"], $q->getTypes());
$this->assertSame([3], $q->getValues()); $this->assertSame([3], $q->getValues());
} }
public function testWhereQuery():void { public function testWhereQuery(): void {
// simple where clause // simple where clause
$q = (new Query("select * from table"))->setWhere("a = ?", "int", 3); $q = (new Query("select * from table"))->setWhere("a = ?", "int", 3);
$this->assertSame("select * from table WHERE a = ?", $q->getQuery()); $this->assertSame("select * from table WHERE a = ?", $q->getQuery());
@ -46,21 +46,21 @@ class TestQuery extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame([2, 4, 1, 3], $q->getValues()); $this->assertSame([2, 4, 1, 3], $q->getValues());
} }
public function testGroupedQuery():void { public function testGroupedQuery(): void {
$q = (new Query("select col1, col2, count(*) as count from table"))->setGroup("col1", "col2"); $q = (new Query("select col1, col2, count(*) as count from table"))->setGroup("col1", "col2");
$this->assertSame("select col1, col2, count(*) as count from table GROUP BY col1, col2", $q->getQuery()); $this->assertSame("select col1, col2, count(*) as count from table GROUP BY col1, col2", $q->getQuery());
$this->assertSame([], $q->getTypes()); $this->assertSame([], $q->getTypes());
$this->assertSame([], $q->getValues()); $this->assertSame([], $q->getValues());
} }
public function testOrderedQuery():void { public function testOrderedQuery(): void {
$q = (new Query("select col1, col2, col3 from table"))->setOrder("col1 desc", "col2")->setOrder("col3 asc"); $q = (new Query("select col1, col2, col3 from table"))->setOrder("col1 desc", "col2")->setOrder("col3 asc");
$this->assertSame("select col1, col2, col3 from table ORDER BY col1 desc, col2, col3 asc", $q->getQuery()); $this->assertSame("select col1, col2, col3 from table ORDER BY col1 desc, col2, col3 asc", $q->getQuery());
$this->assertSame([], $q->getTypes()); $this->assertSame([], $q->getTypes());
$this->assertSame([], $q->getValues()); $this->assertSame([], $q->getValues());
} }
public function testLimitedQuery():void { public function testLimitedQuery(): void {
// no offset // no offset
$q = (new Query("select * from table"))->setLimit(5); $q = (new Query("select * from table"))->setLimit(5);
$this->assertSame("select * from table LIMIT 5", $q->getQuery()); $this->assertSame("select * from table LIMIT 5", $q->getQuery());
@ -78,7 +78,7 @@ class TestQuery extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame([], $q->getValues()); $this->assertSame([], $q->getValues());
} }
public function testQueryWithCommonTableExpression():void { public function testQueryWithCommonTableExpression(): void {
$q = (new Query("select * from table where a in (select * from cte where a = ?)", "int", 1))->setCTE("cte", "select * from other_table where a = ? and b = ?", ["str", "str"], [2, 3]); $q = (new Query("select * from table where a in (select * from cte where a = ?)", "int", 1))->setCTE("cte", "select * from other_table where a = ? and b = ?", ["str", "str"], [2, 3]);
$this->assertSame("WITH RECURSIVE cte as (select * from other_table where a = ? and b = ?) select * from table where a in (select * from cte where a = ?)", $q->getQuery()); $this->assertSame("WITH RECURSIVE cte as (select * from other_table where a = ? and b = ?) select * from table where a in (select * from cte where a = ?)", $q->getQuery());
$this->assertSame(["str", "str", "int"], $q->getTypes()); $this->assertSame(["str", "str", "int"], $q->getTypes());
@ -90,7 +90,7 @@ class TestQuery extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame([2, 3, 4, 5, 1], $q->getValues()); $this->assertSame([2, 3, 4, 5, 1], $q->getValues());
} }
public function testQueryWithPushedCommonTableExpression():void { public function testQueryWithPushedCommonTableExpression(): void {
$q = (new Query("select * from table1"))->setWhere("a between ? and ?", ["datetime", "datetime"], [1, 2]) $q = (new Query("select * from table1"))->setWhere("a between ? and ?", ["datetime", "datetime"], [1, 2])
->setCTE("cte1", "select * from table2 where a = ? and b = ?", ["str", "str"], [3, 4]) ->setCTE("cte1", "select * from table2 where a = ? and b = ?", ["str", "str"], [3, 4])
->pushCTE("cte2") ->pushCTE("cte2")
@ -100,7 +100,7 @@ class TestQuery extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame([3, 4, 1, 2, 5], $q->getValues()); $this->assertSame([3, 4, 1, 2, 5], $q->getValues());
} }
public function testComplexQuery():void { public function testComplexQuery(): void {
$q = (new query("select *, ? as const from table", "datetime", 1)) $q = (new query("select *, ? as const from table", "datetime", 1))
->setWhereNot("b = ?", "bool", 2) ->setWhereNot("b = ?", "bool", 2)
->setGroup("col1", "col2") ->setGroup("col1", "col2")

6
tests/cases/Misc/TestURL.php

@ -15,7 +15,7 @@ class TestURL extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideNormalizations */ /** @dataProvider provideNormalizations */
public function testNormalizeAUrl(string $url, string $exp, string $user = null, string $pass = null):void { public function testNormalizeAUrl(string $url, string $exp, string $user = null, string $pass = null): void {
$this->assertSame($exp, URL::normalize($url, $user, $pass)); $this->assertSame($exp, URL::normalize($url, $user, $pass));
} }
@ -77,7 +77,7 @@ class TestURL extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideQueries */ /** @dataProvider provideQueries */
public function testAppendQueryParameters(string $url, string $query, string $exp):void { public function testAppendQueryParameters(string $url, string $query, string $exp): void {
$this->assertSame($exp, URL::queryAppend($url, $query)); $this->assertSame($exp, URL::queryAppend($url, $query));
} }
@ -93,7 +93,7 @@ class TestURL extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideAbsolutes */ /** @dataProvider provideAbsolutes */
public function testDetermineAbsoluteness(bool $exp, string $url):void { public function testDetermineAbsoluteness(bool $exp, string $url): void {
$this->assertSame($exp, URL::absolute($url)); $this->assertSame($exp, URL::absolute($url));
} }

16
tests/cases/Misc/TestValueInfo.php

@ -16,7 +16,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
self::clearData(); self::clearData();
} }
public function testGetIntegerInfo():void { public function testGetIntegerInfo(): void {
$tests = [ $tests = [
[null, I::NULL], [null, I::NULL],
["", I::NULL], ["", I::NULL],
@ -91,7 +91,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame($exp, I::int($value), "Test returned ".decbin(I::int($value))." for value: ".var_export($value, true)); $this->assertSame($exp, I::int($value), "Test returned ".decbin(I::int($value))." for value: ".var_export($value, true));
} }
} }
public function testGetStringInfo():void { public function testGetStringInfo(): void {
$tests = [ $tests = [
[null, I::NULL], [null, I::NULL],
["", I::VALID | I::EMPTY], ["", I::VALID | I::EMPTY],
@ -162,7 +162,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
} }
} }
public function testValidateDatabaseIdentifier():void { public function testValidateDatabaseIdentifier(): void {
$tests = [ $tests = [
[null, false, true], [null, false, true],
["", false, true], ["", false, true],
@ -234,7 +234,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
} }
} }
public function testValidateBoolean():void { public function testValidateBoolean(): void {
$tests = [ $tests = [
[null, null], [null, null],
["", false], ["", false],
@ -310,7 +310,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideSimpleNormalizationValues */ /** @dataProvider provideSimpleNormalizationValues */
public function testNormalizeSimpleValues($input, string $typeName, $exp, bool $pass, bool $strict, bool $drop):void { public function testNormalizeSimpleValues($input, string $typeName, $exp, bool $pass, bool $strict, bool $drop): void {
$assert = function($exp, $act, string $msg) { $assert = function($exp, $act, string $msg) {
if (is_null($exp)) { if (is_null($exp)) {
$this->assertNull($act, $msg); $this->assertNull($act, $msg);
@ -366,7 +366,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideDateNormalizationValues */ /** @dataProvider provideDateNormalizationValues */
public function testNormalizeDateValues($input, $format, $exp, bool $strict, bool $drop):void { public function testNormalizeDateValues($input, $format, $exp, bool $strict, bool $drop): void {
if ($strict && $drop) { if ($strict && $drop) {
$modeName = "strict drop"; $modeName = "strict drop";
$modeConst = I::M_STRICT | I::M_DROP; $modeConst = I::M_STRICT | I::M_DROP;
@ -397,7 +397,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
} }
} }
public function testNormalizeComplexValues():void { public function testNormalizeComplexValues(): void {
// Array-mode tests // Array-mode tests
$tests = [ $tests = [
[I::T_INT | I::M_DROP, [1, 2, 2.2, 3], [1,2,null,3] ], [I::T_INT | I::M_DROP, [1, 2, 2.2, 3], [1,2,null,3] ],
@ -640,7 +640,7 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
return $out; return $out;
} }
public function testFlattenArray():void { public function testFlattenArray(): void {
$arr = [1, [2, 3, [4, 5]], 6, [[7, 8], 9, 10]]; $arr = [1, [2, 3, [4, 5]], 6, [[7, 8], 9, 10]];
$exp = range(1, 10); $exp = range(1, 10);
$this->assertSame($exp, I::flatten($arr)); $this->assertSame($exp, I::flatten($arr));

28
tests/cases/REST/Fever/TestAPI.php

@ -173,7 +173,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideTokenAuthenticationRequests */ /** @dataProvider provideTokenAuthenticationRequests */
public function testAuthenticateAUserToken(bool $httpRequired, bool $tokenEnforced, string $httpUser = null, array $dataPost, array $dataGet, ResponseInterface $exp):void { public function testAuthenticateAUserToken(bool $httpRequired, bool $tokenEnforced, string $httpUser = null, array $dataPost, array $dataGet, ResponseInterface $exp): void {
self::setConf([ self::setConf([
'userHTTPAuthRequired' => $httpRequired, 'userHTTPAuthRequired' => $httpRequired,
'userSessionEnforced' => $tokenEnforced, 'userSessionEnforced' => $tokenEnforced,
@ -244,7 +244,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
]; ];
} }
public function testListGroups():void { public function testListGroups(): void {
\Phake::when(Arsse::$db)->tagList(Arsse::$user->id)->thenReturn(new Result([ \Phake::when(Arsse::$db)->tagList(Arsse::$user->id)->thenReturn(new Result([
['id' => 1, 'name' => "Fascinating", 'subscriptions' => 2], ['id' => 1, 'name' => "Fascinating", 'subscriptions' => 2],
['id' => 2, 'name' => "Interesting", 'subscriptions' => 2], ['id' => 2, 'name' => "Interesting", 'subscriptions' => 2],
@ -271,7 +271,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $act); $this->assertMessage($exp, $act);
} }
public function testListFeeds():void { public function testListFeeds(): void {
\Phake::when(Arsse::$db)->subscriptionList(Arsse::$user->id)->thenReturn(new Result([ \Phake::when(Arsse::$db)->subscriptionList(Arsse::$user->id)->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", 'favicon' => "http://example.com/favicon.ico"], ['id' => 1, 'feed' => 5, 'title' => "Ankh-Morpork News", 'url' => "http://example.com/feed", 'source' => "http://example.com/", 'edited' => "2019-01-01 21:12:00", 'favicon' => "http://example.com/favicon.ico"],
['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", 'favicon' => ""], ['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", 'favicon' => ""],
@ -299,7 +299,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideItemListContexts */ /** @dataProvider provideItemListContexts */
public function testListItems(string $url, Context $c, bool $desc):void { public function testListItems(string $url, Context $c, bool $desc): void {
$fields = ["id", "subscription", "title", "author", "content", "url", "starred", "unread", "published_date"]; $fields = ["id", "subscription", "title", "author", "content", "url", "starred", "unread", "published_date"];
$order = [$desc ? "id desc" : "id"]; $order = [$desc ? "id desc" : "id"];
\Phake::when(Arsse::$db)->articleList->thenReturn(new Result($this->articles['db'])); \Phake::when(Arsse::$db)->articleList->thenReturn(new Result($this->articles['db']));
@ -329,7 +329,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
]; ];
} }
public function testListItemIds():void { public function testListItemIds(): void {
$saved = [['id' => 1],['id' => 2],['id' => 3]]; $saved = [['id' => 1],['id' => 2],['id' => 3]];
$unread = [['id' => 4],['id' => 5],['id' => 6]]; $unread = [['id' => 4],['id' => 5],['id' => 6]];
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true))->thenReturn(new Result($saved)); \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true))->thenReturn(new Result($saved));
@ -344,7 +344,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $this->h->dispatch($this->req("api&unread_item_ids"))); $this->assertMessage($exp, $this->h->dispatch($this->req("api&unread_item_ids")));
} }
public function testListHotLinks():void { public function testListHotLinks(): void {
// hot links are not actually implemented, so an empty array should be all we get // hot links are not actually implemented, so an empty array should be all we get
$exp = new JsonResponse([ $exp = new JsonResponse([
'links' => [] 'links' => []
@ -353,7 +353,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideMarkingContexts */ /** @dataProvider provideMarkingContexts */
public function testSetMarks(string $post, Context $c, array $data, array $out):void { public function testSetMarks(string $post, Context $c, array $data, array $out): void {
$saved = [['id' => 1],['id' => 2],['id' => 3]]; $saved = [['id' => 1],['id' => 2],['id' => 3]];
$unread = [['id' => 4],['id' => 5],['id' => 6]]; $unread = [['id' => 4],['id' => 5],['id' => 6]];
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true))->thenReturn(new Result($saved)); \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true))->thenReturn(new Result($saved));
@ -371,7 +371,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideMarkingContexts */ /** @dataProvider provideMarkingContexts */
public function testSetMarksWithQuery(string $get, Context $c, array $data, array $out):void { public function testSetMarksWithQuery(string $get, Context $c, array $data, array $out): void {
$saved = [['id' => 1],['id' => 2],['id' => 3]]; $saved = [['id' => 1],['id' => 2],['id' => 3]];
$unread = [['id' => 4],['id' => 5],['id' => 6]]; $unread = [['id' => 4],['id' => 5],['id' => 6]];
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true))->thenReturn(new Result($saved)); \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true))->thenReturn(new Result($saved));
@ -427,7 +427,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideInvalidRequests */ /** @dataProvider provideInvalidRequests */
public function testSendInvalidRequests(ServerRequest $req, ResponseInterface $exp):void { public function testSendInvalidRequests(ServerRequest $req, ResponseInterface $exp): void {
$this->assertMessage($exp, $this->h->dispatch($req)); $this->assertMessage($exp, $this->h->dispatch($req));
} }
@ -439,7 +439,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
]; ];
} }
public function testMakeABaseQuery():void { public function testMakeABaseQuery(): void {
$this->h = \Phake::partialMock(API::class); $this->h = \Phake::partialMock(API::class);
\Phake::when($this->h)->logIn->thenReturn(true); \Phake::when($this->h)->logIn->thenReturn(true);
\Phake::when(Arsse::$db)->subscriptionRefreshed(Arsse::$user->id)->thenReturn(new \DateTimeImmutable("2000-01-01T00:00:00Z")); \Phake::when(Arsse::$db)->subscriptionRefreshed(Arsse::$user->id)->thenReturn(new \DateTimeImmutable("2000-01-01T00:00:00Z"));
@ -467,7 +467,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $act); $this->assertMessage($exp, $act);
} }
public function testUndoReadMarks():void { public function testUndoReadMarks(): void {
$unread = [['id' => 4],['id' => 5],['id' => 6]]; $unread = [['id' => 4],['id' => 5],['id' => 6]];
$out = ['unread_item_ids' => "4,5,6"]; $out = ['unread_item_ids' => "4,5,6"];
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(1), ["marked_date"], ["marked_date desc"])->thenReturn(new Result([['marked_date' => "2000-01-01 00:00:00"]])); \Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(1), ["marked_date"], ["marked_date desc"])->thenReturn(new Result([['marked_date' => "2000-01-01 00:00:00"]]));
@ -483,7 +483,7 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
\Phake::verify(Arsse::$db)->articleMark; // only called one time, above \Phake::verify(Arsse::$db)->articleMark; // only called one time, above
} }
public function testOutputToXml():void { public function testOutputToXml(): void {
\Phake::when($this->h)->processRequest->thenReturn([ \Phake::when($this->h)->processRequest->thenReturn([
'items' => $this->articles['rest'], 'items' => $this->articles['rest'],
'total_items' => 1024, 'total_items' => 1024,
@ -493,13 +493,13 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $act); $this->assertMessage($exp, $act);
} }
public function testListFeedIcons():void { public function testListFeedIcons(): void {
$act = $this->h->dispatch($this->req("api&favicons")); $act = $this->h->dispatch($this->req("api&favicons"));
$exp = new JsonResponse(['favicons' => [['id' => 0, 'data' => API::GENERIC_ICON_TYPE.",".API::GENERIC_ICON_DATA]]]); $exp = new JsonResponse(['favicons' => [['id' => 0, 'data' => API::GENERIC_ICON_TYPE.",".API::GENERIC_ICON_DATA]]]);
$this->assertMessage($exp, $act); $this->assertMessage($exp, $act);
} }
public function testAnswerOptionsRequest():void { public function testAnswerOptionsRequest(): void {
$act = $this->h->dispatch($this->req("api", "", "OPTIONS")); $act = $this->h->dispatch($this->req("api", "", "OPTIONS"));
$exp = new EmptyResponse(204, [ $exp = new EmptyResponse(204, [
'Allow' => "POST", 'Allow' => "POST",

6
tests/cases/REST/Fever/TestUser.php

@ -36,7 +36,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider providePasswordCreations */ /** @dataProvider providePasswordCreations */
public function testRegisterAUserPassword(string $user, string $password = null, $exp):void { public function testRegisterAUserPassword(string $user, string $password = null, $exp): void {
\Phake::when(Arsse::$user)->generatePassword->thenReturn("RANDOM_PASSWORD"); \Phake::when(Arsse::$user)->generatePassword->thenReturn("RANDOM_PASSWORD");
\Phake::when(Arsse::$db)->tokenCreate->thenReturnCallback(function($user, $class, $id = null) { \Phake::when(Arsse::$db)->tokenCreate->thenReturnCallback(function($user, $class, $id = null) {
return $id ?? "RANDOM_TOKEN"; return $id ?? "RANDOM_TOKEN";
@ -66,7 +66,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
]; ];
} }
public function testUnregisterAUser():void { public function testUnregisterAUser(): void {
\Phake::when(Arsse::$db)->tokenRevoke->thenReturn(3); \Phake::when(Arsse::$db)->tokenRevoke->thenReturn(3);
$this->assertTrue($this->u->unregister("jane.doe@example.com")); $this->assertTrue($this->u->unregister("jane.doe@example.com"));
\Phake::verify(Arsse::$db)->tokenRevoke("jane.doe@example.com", "fever.login"); \Phake::verify(Arsse::$db)->tokenRevoke("jane.doe@example.com", "fever.login");
@ -76,7 +76,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideUserAuthenticationRequests */ /** @dataProvider provideUserAuthenticationRequests */
public function testAuthenticateAUserName(string $user, string $password, bool $exp):void { public function testAuthenticateAUserName(string $user, string $password, bool $exp): void {
\Phake::when(Arsse::$db)->tokenLookup->thenThrow(new ExceptionInput("constraintViolation")); \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("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"]); \Phake::when(Arsse::$db)->tokenLookup("fever.login", md5("john.doe@example.com:superman"))->thenReturn(['user' => "john.doe@example.com"]);

60
tests/cases/REST/NextcloudNews/TestV1_2.php

@ -333,13 +333,13 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
return $value; return $value;
} }
public function testSendAuthenticationChallenge():void { public function testSendAuthenticationChallenge(): void {
$exp = new EmptyResponse(401); $exp = new EmptyResponse(401);
$this->assertMessage($exp, $this->req("GET", "/", "", [], false)); $this->assertMessage($exp, $this->req("GET", "/", "", [], false));
} }
/** @dataProvider provideInvalidPaths */ /** @dataProvider provideInvalidPaths */
public function testRespondToInvalidPaths($path, $method, $code, $allow = null):void { public function testRespondToInvalidPaths($path, $method, $code, $allow = null): void {
$exp = new EmptyResponse($code, $allow ? ['Allow' => $allow] : []); $exp = new EmptyResponse($code, $allow ? ['Allow' => $allow] : []);
$this->assertMessage($exp, $this->req($method, $path)); $this->assertMessage($exp, $this->req($method, $path));
} }
@ -371,7 +371,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
]; ];
} }
public function testRespondToInvalidInputTypes():void { public function testRespondToInvalidInputTypes(): void {
$exp = new EmptyResponse(415, ['Accept' => "application/json"]); $exp = new EmptyResponse(415, ['Accept' => "application/json"]);
$this->assertMessage($exp, $this->req("PUT", "/folders/1", '<data/>', ['Content-Type' => "application/xml"])); $this->assertMessage($exp, $this->req("PUT", "/folders/1", '<data/>', ['Content-Type' => "application/xml"]));
$exp = new EmptyResponse(400); $exp = new EmptyResponse(400);
@ -380,7 +380,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideOptionsRequests */ /** @dataProvider provideOptionsRequests */
public function testRespondToOptionsRequests(string $url, string $allow, string $accept):void { public function testRespondToOptionsRequests(string $url, string $allow, string $accept): void {
$exp = new EmptyResponse(204, [ $exp = new EmptyResponse(204, [
'Allow' => $allow, 'Allow' => $allow,
'Accept' => $accept, 'Accept' => $accept,
@ -396,7 +396,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
]; ];
} }
public function testListFolders():void { public function testListFolders(): void {
$list = [ $list = [
['id' => 1, 'name' => "Software", 'parent' => null], ['id' => 1, 'name' => "Software", 'parent' => null],
['id' => 12, 'name' => "Hardware", 'parent' => null], ['id' => 12, 'name' => "Hardware", 'parent' => null],
@ -411,9 +411,9 @@ 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); \Phake::when(Arsse::$db)->folderAdd->thenThrow($output);
} else { } else {
\Phake::when(Arsse::$db)->folderAdd->thenReturn($output); \Phake::when(Arsse::$db)->folderAdd->thenReturn($output);
\Phake::when(Arsse::$db)->folderPropertiesGet->thenReturn($this->v(['id' => $output, 'name' => $input['name'], 'parent' => null])); \Phake::when(Arsse::$db)->folderPropertiesGet->thenReturn($this->v(['id' => $output, 'name' => $input['name'], 'parent' => null]));
@ -441,7 +441,7 @@ 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")); \Phake::when(Arsse::$db)->folderRemove(Arsse::$user->id, 1)->thenReturn(true)->thenThrow(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"));
@ -452,7 +452,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @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); \Phake::when(Arsse::$db)->folderPropertiesSet->thenThrow($output);
} else { } else {
@ -474,7 +474,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
]; ];
} }
public function testRetrieveServerVersion():void { public function testRetrieveServerVersion(): void {
$exp = new Response([ $exp = new Response([
'version' => V1_2::VERSION, 'version' => V1_2::VERSION,
'arsse_version' => Arsse::VERSION, 'arsse_version' => Arsse::VERSION,
@ -482,7 +482,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $this->req("GET", "/version")); $this->assertMessage($exp, $this->req("GET", "/version"));
} }
public function testListSubscriptions():void { public function testListSubscriptions(): void {
$exp1 = [ $exp1 = [
'feeds' => [], 'feeds' => [],
'starredCount' => 0, 'starredCount' => 0,
@ -502,7 +502,7 @@ 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); \Phake::when(Arsse::$db)->subscriptionAdd->thenThrow($id);
} else { } else {
@ -528,7 +528,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
if ($input['folderId'] ?? 0) { if ($input['folderId'] ?? 0) {
\Phake::verify(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, $id, ['folder' => (int) $input['folderId']]); \Phake::verify(Arsse::$db)->subscriptionPropertiesSet(Arsse::$user->id, $id, ['folder' => (int) $input['folderId']]);
} else { } else {
\Phake::verify(Arsse::$db, \Phake::times(0))->subscriptionPropertiesSet; \Phake::verify(Arsse::$db, \Phake::times(0))->subscriptionPropertiesSet;
} }
} }
} }
@ -545,7 +545,7 @@ 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")); \Phake::when(Arsse::$db)->subscriptionRemove(Arsse::$user->id, 1)->thenReturn(true)->thenThrow(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"));
@ -555,7 +555,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
\Phake::verify(Arsse::$db, \Phake::times(2))->subscriptionRemove(Arsse::$user->id, 1); \Phake::verify(Arsse::$db, \Phake::times(2))->subscriptionRemove(Arsse::$user->id, 1);
} }
public function testMoveASubscription():void { public function testMoveASubscription(): void {
$in = [ $in = [
['folderId' => 0], ['folderId' => 0],
['folderId' => 42], ['folderId' => 42],
@ -583,7 +583,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/move", json_encode($in[5]))); $this->assertMessage($exp, $this->req("PUT", "/feeds/1/move", json_encode($in[5])));
} }
public function testRenameASubscription():void { public function testRenameASubscription(): void {
$in = [ $in = [
['feedTitle' => null], ['feedTitle' => null],
['feedTitle' => "Ook"], ['feedTitle' => "Ook"],
@ -613,7 +613,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $this->req("PUT", "/feeds/1/rename", json_encode($in[6]))); $this->assertMessage($exp, $this->req("PUT", "/feeds/1/rename", json_encode($in[6])));
} }
public function testListStaleFeeds():void { public function testListStaleFeeds(): void {
$out = [ $out = [
[ [
'id' => 42, 'id' => 42,
@ -629,7 +629,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $this->req("GET", "/feeds/all")); $this->assertMessage($exp, $this->req("GET", "/feeds/all"));
} }
public function testUpdateAFeed():void { public function testUpdateAFeed(): void {
$in = [ $in = [
['feedId' => 42], // valid ['feedId' => 42], // valid
['feedId' => 2112], // feed does not exist ['feedId' => 2112], // feed does not exist
@ -650,7 +650,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $this->req("GET", "/feeds/update", json_encode($in[4]))); $this->assertMessage($exp, $this->req("GET", "/feeds/update", json_encode($in[4])));
} }
public function testListArticles():void { public function testListArticles(): void {
$t = new \DateTime; $t = new \DateTime;
$in = [ $in = [
['type' => 0, 'id' => 42], // type=0 => subscription/feed ['type' => 0, 'id' => 42], // type=0 => subscription/feed
@ -704,7 +704,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
\Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(5), $this->anything(), ["edition desc"]); \Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(5), $this->anything(), ["edition desc"]);
} }
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))->thenReturn(42); \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->folder(1)->latestEdition(2112))->thenReturn(42);
@ -719,7 +719,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $this->req("PUT", "/folders/42/read", $in)); $this->assertMessage($exp, $this->req("PUT", "/folders/42/read", $in));
} }
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))->thenReturn(42); \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->subscription(1)->latestEdition(2112))->thenReturn(42);
@ -734,7 +734,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $this->req("PUT", "/feeds/42/read", $in)); $this->assertMessage($exp, $this->req("PUT", "/feeds/42/read", $in));
} }
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); \Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $read, (new Context)->latestEdition(2112))->thenReturn(42);
@ -746,7 +746,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $this->req("PUT", "/items/read?newestItemId=ook")); $this->assertMessage($exp, $this->req("PUT", "/items/read?newestItemId=ook"));
} }
public function testChangeMarksOfASingleArticle():void { public function testChangeMarksOfASingleArticle(): void {
$read = ['read' => true]; $read = ['read' => true];
$unread = ['read' => false]; $unread = ['read' => false];
$star = ['starred' => true]; $star = ['starred' => true];
@ -772,7 +772,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
\Phake::verify(Arsse::$db, \Phake::times(8))->articleMark(Arsse::$user->id, $this->anything(), $this->anything()); \Phake::verify(Arsse::$db, \Phake::times(8))->articleMark(Arsse::$user->id, $this->anything(), $this->anything());
} }
public function testChangeMarksOfMultipleArticles():void { public function testChangeMarksOfMultipleArticles(): void {
$read = ['read' => true]; $read = ['read' => true];
$unread = ['read' => false]; $unread = ['read' => false];
$star = ['starred' => true]; $star = ['starred' => true];
@ -827,7 +827,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
\Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $unstar, (new Context)->articles($in[1])); \Phake::verify(Arsse::$db, \Phake::atLeast(1))->articleMark(Arsse::$user->id, $unstar, (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);
@ -847,21 +847,21 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $this->req("GET", "/status")); $this->assertMessage($exp, $this->req("GET", "/status"));
} }
public function testCleanUpBeforeUpdate():void { public function testCleanUpBeforeUpdate(): void {
\Phake::when(Arsse::$db)->feedCleanup()->thenReturn(true); \Phake::when(Arsse::$db)->feedCleanup()->thenReturn(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(); \Phake::verify(Arsse::$db)->feedCleanup();
} }
public function testCleanUpAfterUpdate():void { public function testCleanUpAfterUpdate(): void {
\Phake::when(Arsse::$db)->articleCleanup()->thenReturn(true); \Phake::when(Arsse::$db)->articleCleanup()->thenReturn(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(); \Phake::verify(Arsse::$db)->articleCleanup();
} }
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' => Arsse::$user->id,
@ -872,7 +872,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $act); $this->assertMessage($exp, $act);
} }
public function testPreferJsonOverQueryParameters():void { public function testPreferJsonOverQueryParameters(): void {
$in = ['name' => "Software"]; $in = ['name' => "Software"];
$url = "/folders?name=Hardware"; $url = "/folders?name=Hardware";
$out1 = ['id' => 1, 'name' => "Software"]; $out1 = ['id' => 1, 'name' => "Software"];
@ -885,7 +885,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $this->req("POST", "/folders?name=Hardware", json_encode($in))); $this->assertMessage($exp, $this->req("POST", "/folders?name=Hardware", json_encode($in)));
} }
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([])); \Phake::when(Arsse::$db)->articleList->thenReturn(new Result([]));

8
tests/cases/REST/NextcloudNews/TestVersions.php

@ -25,24 +25,24 @@ class TestVersions extends \JKingWeb\Arsse\Test\AbstractTest {
return (new Versions)->dispatch($req); return (new Versions)->dispatch($req);
} }
public function testFetchVersionList():void { public function testFetchVersionList(): void {
$exp = new Response(['apiLevels' => ['v1-2']]); $exp = new Response(['apiLevels' => ['v1-2']]);
$this->assertMessage($exp, $this->req("GET", "/")); $this->assertMessage($exp, $this->req("GET", "/"));
$this->assertMessage($exp, $this->req("GET", "/")); $this->assertMessage($exp, $this->req("GET", "/"));
$this->assertMessage($exp, $this->req("GET", "/")); $this->assertMessage($exp, $this->req("GET", "/"));
} }
public function testRespondToOptionsRequest():void { public function testRespondToOptionsRequest(): void {
$exp = new EmptyResponse(204, ['Allow' => "HEAD,GET"]); $exp = new EmptyResponse(204, ['Allow' => "HEAD,GET"]);
$this->assertMessage($exp, $this->req("OPTIONS", "/")); $this->assertMessage($exp, $this->req("OPTIONS", "/"));
} }
public function testUseIncorrectMethod():void { public function testUseIncorrectMethod(): void {
$exp = new EmptyResponse(405, ['Allow' => "HEAD,GET"]); $exp = new EmptyResponse(405, ['Allow' => "HEAD,GET"]);
$this->assertMessage($exp, $this->req("POST", "/")); $this->assertMessage($exp, $this->req("POST", "/"));
} }
public function testUseIncorrectPath():void { public function testUseIncorrectPath(): void {
$exp = new EmptyResponse(404); $exp = new EmptyResponse(404);
$this->assertMessage($exp, $this->req("GET", "/ook")); $this->assertMessage($exp, $this->req("GET", "/ook"));
$this->assertMessage($exp, $this->req("OPTIONS", "/ook")); $this->assertMessage($exp, $this->req("OPTIONS", "/ook"));

18
tests/cases/REST/TestREST.php

@ -25,7 +25,7 @@ use Laminas\Diactoros\Response\EmptyResponse;
class TestREST extends \JKingWeb\Arsse\Test\AbstractTest { class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideApiMatchData */ /** @dataProvider provideApiMatchData */
public function testMatchAUrlToAnApi($apiList, string $input, array $exp):void { public function testMatchAUrlToAnApi($apiList, string $input, array $exp): void {
$r = new REST($apiList); $r = new REST($apiList);
try { try {
$out = $r->apiMatch($input); $out = $r->apiMatch($input);
@ -61,7 +61,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideAuthenticableRequests */ /** @dataProvider provideAuthenticableRequests */
public function testAuthenticateRequests(array $serverParams, array $expAttr):void { public function testAuthenticateRequests(array $serverParams, array $expAttr): void {
$r = new REST(); $r = new REST();
// create a mock user manager // create a mock user manager
Arsse::$user = \Phake::mock(User::class); Arsse::$user = \Phake::mock(User::class);
@ -93,7 +93,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
]; ];
} }
public function testSendAuthenticationChallenges():void { public function testSendAuthenticationChallenges(): void {
self::setConf(); self::setConf();
$r = new REST(); $r = new REST();
$in = new EmptyResponse(401); $in = new EmptyResponse(401);
@ -106,7 +106,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideUnnormalizedOrigins */ /** @dataProvider provideUnnormalizedOrigins */
public function testNormalizeOrigins(string $origin, string $exp, array $ports = null):void { public function testNormalizeOrigins(string $origin, string $exp, array $ports = null): void {
$r = new REST(); $r = new REST();
$act = $r->corsNormalizeOrigin($origin, $ports); $act = $r->corsNormalizeOrigin($origin, $ports);
$this->assertSame($exp, $act); $this->assertSame($exp, $act);
@ -149,7 +149,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideCorsNegotiations */ /** @dataProvider provideCorsNegotiations */
public function testNegotiateCors($origin, bool $exp, string $allowed = null, string $denied = null):void { public function testNegotiateCors($origin, bool $exp, string $allowed = null, string $denied = null): void {
self::setConf(); self::setConf();
$r = \Phake::partialMock(REST::class); $r = \Phake::partialMock(REST::class);
\Phake::when($r)->corsNormalizeOrigin->thenReturnCallback(function($origin) { \Phake::when($r)->corsNormalizeOrigin->thenReturnCallback(function($origin) {
@ -187,7 +187,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideCorsHeaders */ /** @dataProvider provideCorsHeaders */
public function testAddCorsHeaders(string $reqMethod, array $reqHeaders, array $resHeaders, array $expHeaders):void { public function testAddCorsHeaders(string $reqMethod, array $reqHeaders, array $resHeaders, array $expHeaders): void {
$r = new REST(); $r = new REST();
$req = new Request("", $reqMethod, "php://memory", $reqHeaders); $req = new Request("", $reqMethod, "php://memory", $reqHeaders);
$res = new EmptyResponse(204, $resHeaders); $res = new EmptyResponse(204, $resHeaders);
@ -251,7 +251,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideUnnormalizedResponses */ /** @dataProvider provideUnnormalizedResponses */
public function testNormalizeHttpResponses(ResponseInterface $res, ResponseInterface $exp, RequestInterface $req = null):void { public function testNormalizeHttpResponses(ResponseInterface $res, ResponseInterface $exp, RequestInterface $req = null): void {
$r = \Phake::partialMock(REST::class); $r = \Phake::partialMock(REST::class);
\Phake::when($r)->corsNegotiate->thenReturn(true); \Phake::when($r)->corsNegotiate->thenReturn(true);
\Phake::when($r)->challenge->thenReturnCallback(function($res) { \Phake::when($r)->challenge->thenReturnCallback(function($res) {
@ -286,7 +286,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
]; ];
} }
public function testCreateHandlers():void { public function testCreateHandlers(): void {
$r = new REST(); $r = new REST();
foreach (REST::API_LIST as $api) { foreach (REST::API_LIST as $api) {
$class = $api['class']; $class = $api['class'];
@ -295,7 +295,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideMockRequests */ /** @dataProvider provideMockRequests */
public function testDispatchRequests(ServerRequest $req, string $method, bool $called, string $class = "", string $target =""):void { public function testDispatchRequests(ServerRequest $req, string $method, bool $called, string $class = "", string $target =""): void {
$r = \Phake::partialMock(REST::class); $r = \Phake::partialMock(REST::class);
\Phake::when($r)->normalizeResponse->thenReturnCallback(function($res) { \Phake::when($r)->normalizeResponse->thenReturnCallback(function($res) {
return $res; return $res;

74
tests/cases/REST/TinyTinyRSS/TestAPI.php

@ -178,7 +178,7 @@ LONG_STRING;
self::clearData(); self::clearData();
} }
public function testHandleInvalidPaths():void { public function testHandleInvalidPaths(): void {
$exp = $this->respErr("MALFORMED_INPUT", [], null); $exp = $this->respErr("MALFORMED_INPUT", [], null);
$this->assertMessage($exp, $this->req(null, "POST", "", "")); $this->assertMessage($exp, $this->req(null, "POST", "", ""));
$this->assertMessage($exp, $this->req(null, "POST", "/", "")); $this->assertMessage($exp, $this->req(null, "POST", "/", ""));
@ -187,7 +187,7 @@ LONG_STRING;
$this->assertMessage($exp, $this->req(null, "POST", "/bad/path", "")); $this->assertMessage($exp, $this->req(null, "POST", "/bad/path", ""));
} }
public function testHandleOptionsRequest():void { public function testHandleOptionsRequest(): void {
$exp = new EmptyResponse(204, [ $exp = new EmptyResponse(204, [
'Allow' => "POST", 'Allow' => "POST",
'Accept' => "application/json, text/json", 'Accept' => "application/json, text/json",
@ -195,14 +195,14 @@ LONG_STRING;
$this->assertMessage($exp, $this->req(null, "OPTIONS", "", "")); $this->assertMessage($exp, $this->req(null, "OPTIONS", "", ""));
} }
public function testHandleInvalidData():void { public function testHandleInvalidData(): void {
$exp = $this->respErr("MALFORMED_INPUT", [], null); $exp = $this->respErr("MALFORMED_INPUT", [], null);
$this->assertMessage($exp, $this->req(null, "POST", "", "This is not valid JSON data")); $this->assertMessage($exp, $this->req(null, "POST", "", "This is not valid JSON data"));
$this->assertMessage($exp, $this->req(null, "POST", "", "")); // lack of data is also an error $this->assertMessage($exp, $this->req(null, "POST", "", "")); // lack of data is also an error
} }
/** @dataProvider provideLoginRequests */ /** @dataProvider provideLoginRequests */
public function testLogIn(array $conf, $httpUser, array $data, $sessions):void { public function testLogIn(array $conf, $httpUser, array $data, $sessions): void {
Arsse::$user->id = null; Arsse::$user->id = null;
self::setConf($conf); self::setConf($conf);
\Phake::when(Arsse::$user)->auth->thenReturn(false); \Phake::when(Arsse::$user)->auth->thenReturn(false);
@ -236,7 +236,7 @@ LONG_STRING;
} }
/** @dataProvider provideResumeRequests */ /** @dataProvider provideResumeRequests */
public function testValidateASession(array $conf, $httpUser, string $data, $result):void { public function testValidateASession(array $conf, $httpUser, string $data, $result): void {
Arsse::$user->id = null; Arsse::$user->id = null;
self::setConf($conf); self::setConf($conf);
\Phake::when(Arsse::$db)->sessionResume("PriestsOfSyrinx")->thenReturn([ \Phake::when(Arsse::$db)->sessionResume("PriestsOfSyrinx")->thenReturn([
@ -520,7 +520,7 @@ LONG_STRING;
} }
} }
public function testHandleGenericError():void { public function testHandleGenericError(): void {
\Phake::when(Arsse::$user)->auth(Arsse::$user->id, $this->anything())->thenThrow(new \JKingWeb\Arsse\Db\ExceptionTimeout("general")); \Phake::when(Arsse::$user)->auth(Arsse::$user->id, $this->anything())->thenThrow(new \JKingWeb\Arsse\Db\ExceptionTimeout("general"));
$data = [ $data = [
'op' => "login", 'op' => "login",
@ -531,7 +531,7 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($data)); $this->assertMessage($exp, $this->req($data));
} }
public function testLogOut():void { public function testLogOut(): void {
\Phake::when(Arsse::$db)->sessionDestroy->thenReturn(true); \Phake::when(Arsse::$db)->sessionDestroy->thenReturn(true);
$data = [ $data = [
'op' => "logout", 'op' => "logout",
@ -542,7 +542,7 @@ LONG_STRING;
\Phake::verify(Arsse::$db)->sessionDestroy(Arsse::$user->id, "PriestsOfSyrinx"); \Phake::verify(Arsse::$db)->sessionDestroy(Arsse::$user->id, "PriestsOfSyrinx");
} }
public function testHandleUnknownMethods():void { public function testHandleUnknownMethods(): void {
$exp = $this->respErr("UNKNOWN_METHOD", ['method' => "thisMethodDoesNotExist"]); $exp = $this->respErr("UNKNOWN_METHOD", ['method' => "thisMethodDoesNotExist"]);
$data = [ $data = [
'op' => "thisMethodDoesNotExist", 'op' => "thisMethodDoesNotExist",
@ -551,7 +551,7 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($data)); $this->assertMessage($exp, $this->req($data));
} }
public function testHandleMixedCaseMethods():void { public function testHandleMixedCaseMethods(): void {
$data = [ $data = [
'op' => "isLoggedIn", 'op' => "isLoggedIn",
'sid' => "PriestsOfSyrinx", 'sid' => "PriestsOfSyrinx",
@ -566,7 +566,7 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($data)); $this->assertMessage($exp, $this->req($data));
} }
public function testRetrieveServerVersion():void { public function testRetrieveServerVersion(): void {
$data = [ $data = [
'op' => "getVersion", 'op' => "getVersion",
'sid' => "PriestsOfSyrinx", 'sid' => "PriestsOfSyrinx",
@ -578,7 +578,7 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($data)); $this->assertMessage($exp, $this->req($data));
} }
public function testRetrieveProtocolLevel():void { public function testRetrieveProtocolLevel(): void {
$data = [ $data = [
'op' => "getApiLevel", 'op' => "getApiLevel",
'sid' => "PriestsOfSyrinx", 'sid' => "PriestsOfSyrinx",
@ -587,7 +587,7 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($data)); $this->assertMessage($exp, $this->req($data));
} }
public function testAddACategory():void { public function testAddACategory(): void {
$in = [ $in = [
['op' => "addCategory", 'sid' => "PriestsOfSyrinx", 'caption' => "Software"], ['op' => "addCategory", 'sid' => "PriestsOfSyrinx", 'caption' => "Software"],
['op' => "addCategory", 'sid' => "PriestsOfSyrinx", 'caption' => "Hardware", 'parent_id' => 1], ['op' => "addCategory", 'sid' => "PriestsOfSyrinx", 'caption' => "Hardware", 'parent_id' => 1],
@ -638,7 +638,7 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($in[5])); $this->assertMessage($exp, $this->req($in[5]));
} }
public function testRemoveACategory():void { public function testRemoveACategory(): void {
$in = [ $in = [
['op' => "removeCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 42], ['op' => "removeCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 42],
['op' => "removeCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 2112], ['op' => "removeCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 2112],
@ -661,7 +661,7 @@ LONG_STRING;
\Phake::verify(Arsse::$db, \Phake::times(3))->folderRemove(Arsse::$user->id, $this->anything()); \Phake::verify(Arsse::$db, \Phake::times(3))->folderRemove(Arsse::$user->id, $this->anything());
} }
public function testMoveACategory():void { public function testMoveACategory(): void {
$in = [ $in = [
['op' => "moveCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 42, 'parent_id' => 1], ['op' => "moveCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 42, 'parent_id' => 1],
['op' => "moveCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 2112, 'parent_id' => 2], ['op' => "moveCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 2112, 'parent_id' => 2],
@ -713,7 +713,7 @@ LONG_STRING;
\Phake::verify(Arsse::$db, \Phake::times(5))->folderPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything()); \Phake::verify(Arsse::$db, \Phake::times(5))->folderPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything());
} }
public function testRenameACategory():void { public function testRenameACategory(): void {
$in = [ $in = [
['op' => "renameCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 42, 'caption' => "Ook"], ['op' => "renameCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 42, 'caption' => "Ook"],
['op' => "renameCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 2112, 'caption' => "Eek"], ['op' => "renameCategory", 'sid' => "PriestsOfSyrinx", 'category_id' => 2112, 'caption' => "Eek"],
@ -753,7 +753,7 @@ LONG_STRING;
\Phake::verify(Arsse::$db, \Phake::times(3))->folderPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything()); \Phake::verify(Arsse::$db, \Phake::times(3))->folderPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything());
} }
public function testAddASubscription():void { public function testAddASubscription(): void {
$in = [ $in = [
['op' => "subscribeToFeed", 'sid' => "PriestsOfSyrinx", 'feed_url' => "http://example.com/0"], ['op' => "subscribeToFeed", 'sid' => "PriestsOfSyrinx", 'feed_url' => "http://example.com/0"],
['op' => "subscribeToFeed", 'sid' => "PriestsOfSyrinx", 'feed_url' => "http://example.com/1", 'category_id' => 42], ['op' => "subscribeToFeed", 'sid' => "PriestsOfSyrinx", 'feed_url' => "http://example.com/1", 'category_id' => 42],
@ -828,7 +828,7 @@ LONG_STRING;
\Phake::verify(Arsse::$db, \Phake::times(0))->subscriptionPropertiesSet(Arsse::$user->id, 4, ['folder' => 1]); \Phake::verify(Arsse::$db, \Phake::times(0))->subscriptionPropertiesSet(Arsse::$user->id, 4, ['folder' => 1]);
} }
public function testRemoveASubscription():void { public function testRemoveASubscription(): void {
$in = [ $in = [
['op' => "unsubscribeFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42], ['op' => "unsubscribeFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42],
['op' => "unsubscribeFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2112], ['op' => "unsubscribeFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2112],
@ -850,7 +850,7 @@ LONG_STRING;
\Phake::verify(Arsse::$db, \Phake::times(5))->subscriptionRemove(Arsse::$user->id, $this->anything()); \Phake::verify(Arsse::$db, \Phake::times(5))->subscriptionRemove(Arsse::$user->id, $this->anything());
} }
public function testMoveASubscription():void { public function testMoveASubscription(): void {
$in = [ $in = [
['op' => "moveFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'category_id' => 1], ['op' => "moveFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'category_id' => 1],
['op' => "moveFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2112, 'category_id' => 2], ['op' => "moveFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2112, 'category_id' => 2],
@ -892,7 +892,7 @@ LONG_STRING;
\Phake::verify(Arsse::$db, \Phake::times(4))->subscriptionPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything()); \Phake::verify(Arsse::$db, \Phake::times(4))->subscriptionPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything());
} }
public function testRenameASubscription():void { public function testRenameASubscription(): void {
$in = [ $in = [
['op' => "renameFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'caption' => "Ook"], ['op' => "renameFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 42, 'caption' => "Ook"],
['op' => "renameFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2112, 'caption' => "Eek"], ['op' => "renameFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2112, 'caption' => "Eek"],
@ -934,7 +934,7 @@ LONG_STRING;
\Phake::verify(Arsse::$db)->subscriptionPropertiesSet(...$db[2]); \Phake::verify(Arsse::$db)->subscriptionPropertiesSet(...$db[2]);
} }
public function testRetrieveTheGlobalUnreadCount():void { public function testRetrieveTheGlobalUnreadCount(): void {
$in = ['op' => "getUnread", 'sid' => "PriestsOfSyrinx"]; $in = ['op' => "getUnread", 'sid' => "PriestsOfSyrinx"];
\Phake::when(Arsse::$db)->subscriptionList(Arsse::$user->id)->thenReturn(new Result($this->v([ \Phake::when(Arsse::$db)->subscriptionList(Arsse::$user->id)->thenReturn(new Result($this->v([
['id' => 1, 'unread' => 2112], ['id' => 1, 'unread' => 2112],
@ -945,7 +945,7 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($in)); $this->assertMessage($exp, $this->req($in));
} }
public function testRetrieveTheServerConfiguration():void { public function testRetrieveTheServerConfiguration(): void {
$in = ['op' => "getConfig", 'sid' => "PriestsOfSyrinx"]; $in = ['op' => "getConfig", 'sid' => "PriestsOfSyrinx"];
$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);
@ -960,7 +960,7 @@ LONG_STRING;
$this->assertMessage($this->respGood($exp[1]), $this->req($in)); $this->assertMessage($this->respGood($exp[1]), $this->req($in));
} }
public function testUpdateAFeed():void { public function testUpdateAFeed(): void {
$in = [ $in = [
['op' => "updateFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 1], ['op' => "updateFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 1],
['op' => "updateFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2], ['op' => "updateFeed", 'sid' => "PriestsOfSyrinx", 'feed_id' => 2],
@ -980,7 +980,7 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($in[3])); $this->assertMessage($exp, $this->req($in[3]));
} }
public function testAddALabel():void { public function testAddALabel(): void {
$in = [ $in = [
['op' => "addLabel", 'sid' => "PriestsOfSyrinx", 'caption' => "Software"], ['op' => "addLabel", 'sid' => "PriestsOfSyrinx", 'caption' => "Software"],
['op' => "addLabel", 'sid' => "PriestsOfSyrinx", 'caption' => "Hardware",], ['op' => "addLabel", 'sid' => "PriestsOfSyrinx", 'caption' => "Hardware",],
@ -1025,7 +1025,7 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($in[4])); $this->assertMessage($exp, $this->req($in[4]));
} }
public function testRemoveALabel():void { public function testRemoveALabel(): void {
$in = [ $in = [
['op' => "removeLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => -1042], ['op' => "removeLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => -1042],
['op' => "removeLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => -2112], ['op' => "removeLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => -2112],
@ -1053,7 +1053,7 @@ LONG_STRING;
\Phake::verify(Arsse::$db)->labelRemove(Arsse::$user->id, 1088); \Phake::verify(Arsse::$db)->labelRemove(Arsse::$user->id, 1088);
} }
public function testRenameALabel():void { public function testRenameALabel(): void {
$in = [ $in = [
['op' => "renameLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => -1042, 'caption' => "Ook"], ['op' => "renameLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => -1042, 'caption' => "Ook"],
['op' => "renameLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => -2112, 'caption' => "Eek"], ['op' => "renameLabel", 'sid' => "PriestsOfSyrinx", 'label_id' => -2112, 'caption' => "Eek"],
@ -1099,7 +1099,7 @@ LONG_STRING;
\Phake::verify(Arsse::$db, \Phake::times(6))->labelPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything()); \Phake::verify(Arsse::$db, \Phake::times(6))->labelPropertiesSet(Arsse::$user->id, $this->anything(), $this->anything());
} }
public function testRetrieveCategoryLists():void { public function testRetrieveCategoryLists(): void {
$in = [ $in = [
['op' => "getCategories", 'sid' => "PriestsOfSyrinx", 'include_empty' => true], ['op' => "getCategories", 'sid' => "PriestsOfSyrinx", 'include_empty' => true],
['op' => "getCategories", 'sid' => "PriestsOfSyrinx"], ['op' => "getCategories", 'sid' => "PriestsOfSyrinx"],
@ -1171,7 +1171,7 @@ LONG_STRING;
} }
} }
public function testRetrieveCounterList():void { public function testRetrieveCounterList(): void {
$in = ['op' => "getCounters", 'sid' => "PriestsOfSyrinx"]; $in = ['op' => "getCounters", 'sid' => "PriestsOfSyrinx"];
\Phake::when(Arsse::$db)->folderList($this->anything())->thenReturn(new Result($this->v($this->folders))); \Phake::when(Arsse::$db)->folderList($this->anything())->thenReturn(new Result($this->v($this->folders)));
\Phake::when(Arsse::$db)->subscriptionList($this->anything())->thenReturn(new Result($this->v($this->subscriptions))); \Phake::when(Arsse::$db)->subscriptionList($this->anything())->thenReturn(new Result($this->v($this->subscriptions)));
@ -1206,7 +1206,7 @@ LONG_STRING;
$this->assertMessage($this->respGood($exp), $this->req($in)); $this->assertMessage($this->respGood($exp), $this->req($in));
} }
public function testRetrieveTheLabelList():void { public function testRetrieveTheLabelList(): void {
$in = [ $in = [
['op' => "getLabels", 'sid' => "PriestsOfSyrinx"], ['op' => "getLabels", 'sid' => "PriestsOfSyrinx"],
['op' => "getLabels", 'sid' => "PriestsOfSyrinx", 'article_id' => 1], ['op' => "getLabels", 'sid' => "PriestsOfSyrinx", 'article_id' => 1],
@ -1251,7 +1251,7 @@ LONG_STRING;
} }
} }
public function testAssignArticlesToALabel():void { public function testAssignArticlesToALabel(): void {
$list = [ $list = [
range(1, 100), range(1, 100),
range(1, 50), range(1, 50),
@ -1289,7 +1289,7 @@ LONG_STRING;
$this->assertMessage($exp, $this->req($in[6])); $this->assertMessage($exp, $this->req($in[6]));
} }
public function testRetrieveFeedTree():void { public function testRetrieveFeedTree(): void {
$in = [ $in = [
['op' => "getFeedTree", 'sid' => "PriestsOfSyrinx", 'include_empty' => true], ['op' => "getFeedTree", 'sid' => "PriestsOfSyrinx", 'include_empty' => true],
['op' => "getFeedTree", 'sid' => "PriestsOfSyrinx"], ['op' => "getFeedTree", 'sid' => "PriestsOfSyrinx"],
@ -1306,7 +1306,7 @@ LONG_STRING;
$this->assertMessage($this->respGood($exp), $this->req($in[1])); $this->assertMessage($this->respGood($exp), $this->req($in[1]));
} }
public function testMarkFeedsAsRead():void { public function testMarkFeedsAsRead(): void {
$in1 = [ $in1 = [
// no-ops // no-ops
['op' => "catchupFeed", 'sid' => "PriestsOfSyrinx"], ['op' => "catchupFeed", 'sid' => "PriestsOfSyrinx"],
@ -1357,7 +1357,7 @@ LONG_STRING;
\Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], $this->equalTo((new Context)->modifiedSince($t), 2)); // within two seconds \Phake::verify(Arsse::$db)->articleMark($this->anything(), ['read' => true], $this->equalTo((new Context)->modifiedSince($t), 2)); // within two seconds
} }
public function testRetrieveFeedList():void { public function testRetrieveFeedList(): void {
$in1 = [ $in1 = [
['op' => "getFeeds", 'sid' => "PriestsOfSyrinx"], ['op' => "getFeeds", 'sid' => "PriestsOfSyrinx"],
['op' => "getFeeds", 'sid' => "PriestsOfSyrinx", 'cat_id' => -1], ['op' => "getFeeds", 'sid' => "PriestsOfSyrinx", 'cat_id' => -1],
@ -1519,7 +1519,7 @@ LONG_STRING;
return $out; return $out;
} }
public function testChangeArticles():void { public function testChangeArticles(): void {
$in = [ $in = [
['op' => "updateArticle", 'sid' => "PriestsOfSyrinx"], ['op' => "updateArticle", 'sid' => "PriestsOfSyrinx"],
['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1"], ['op' => "updateArticle", 'sid' => "PriestsOfSyrinx", 'article_ids' => "42, 2112, -1"],
@ -1604,7 +1604,7 @@ LONG_STRING;
} }
} }
public function testListArticles():void { public function testListArticles(): void {
$in = [ $in = [
// error conditions // error conditions
['op' => "getArticle", 'sid' => "PriestsOfSyrinx"], ['op' => "getArticle", 'sid' => "PriestsOfSyrinx"],
@ -1693,7 +1693,7 @@ LONG_STRING;
$this->assertMessage($this->respGood([$exp[0]]), $this->req($in[5])); $this->assertMessage($this->respGood([$exp[0]]), $this->req($in[5]));
} }
public function testRetrieveCompactHeadlines():void { public function testRetrieveCompactHeadlines(): void {
$in1 = [ $in1 = [
// erroneous input // erroneous input
['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx"], ['op' => "getCompactHeadlines", 'sid' => "PriestsOfSyrinx"],
@ -1779,7 +1779,7 @@ LONG_STRING;
} }
} }
public function testRetrieveFullHeadlines():void { public function testRetrieveFullHeadlines(): void {
$in1 = [ $in1 = [
// empty results // empty results
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 0], ['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => 0],
@ -1895,7 +1895,7 @@ LONG_STRING;
} }
} }
public function testRetrieveFullHeadlinesCheckingExtraFields():void { public function testRetrieveFullHeadlinesCheckingExtraFields(): void {
$in = [ $in = [
// empty results // empty results
['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4], ['op' => "getHeadlines", 'sid' => "PriestsOfSyrinx", 'feed_id' => -4],

4
tests/cases/REST/TinyTinyRSS/TestIcon.php

@ -48,7 +48,7 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
return $this->req($target, $method, ""); return $this->req($target, $method, "");
} }
public function testRetrieveFavion():void { public function testRetrieveFavion(): void {
\Phake::when(Arsse::$db)->subscriptionFavicon->thenReturn(""); \Phake::when(Arsse::$db)->subscriptionFavicon->thenReturn("");
\Phake::when(Arsse::$db)->subscriptionFavicon(42, $this->anything())->thenReturn("http://example.com/favicon.ico"); \Phake::when(Arsse::$db)->subscriptionFavicon(42, $this->anything())->thenReturn("http://example.com/favicon.ico");
\Phake::when(Arsse::$db)->subscriptionFavicon(2112, $this->anything())->thenReturn("http://example.net/logo.png"); \Phake::when(Arsse::$db)->subscriptionFavicon(2112, $this->anything())->thenReturn("http://example.net/logo.png");
@ -71,7 +71,7 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertMessage($exp, $this->req("2112.ico", "PUT")); $this->assertMessage($exp, $this->req("2112.ico", "PUT"));
} }
public function testRetrieveFavionWithHttpAuthentication():void { public function testRetrieveFavionWithHttpAuthentication(): void {
$url = "http://example.org/icon.gif\r\nLocation: http://bad.example.com/"; $url = "http://example.org/icon.gif\r\nLocation: http://bad.example.com/";
\Phake::when(Arsse::$db)->subscriptionFavicon->thenReturn(""); \Phake::when(Arsse::$db)->subscriptionFavicon->thenReturn("");
\Phake::when(Arsse::$db)->subscriptionFavicon(42, $this->user)->thenReturn($url); \Phake::when(Arsse::$db)->subscriptionFavicon(42, $this->user)->thenReturn($url);

2
tests/cases/REST/TinyTinyRSS/TestSearch.php

@ -118,7 +118,7 @@ class TestSearch extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideSearchStrings */ /** @dataProvider provideSearchStrings */
public function testApplySearchToContext(string $search, $exp):void { public function testApplySearchToContext(string $search, $exp): void {
$act = Search::parse($search); $act = Search::parse($search);
$this->assertEquals($exp, $act); $this->assertEquals($exp, $act);
} }

8
tests/cases/Service/TestSerial.php

@ -19,16 +19,16 @@ class TestSerial extends \JKingWeb\Arsse\Test\AbstractTest {
Arsse::$db = \Phake::mock(Database::class); Arsse::$db = \Phake::mock(Database::class);
} }
public function testConstruct():void { public function testConstruct(): void {
$this->assertTrue(Driver::requirementsMet()); $this->assertTrue(Driver::requirementsMet());
$this->assertInstanceOf(DriverInterface::class, new Driver); $this->assertInstanceOf(DriverInterface::class, new Driver);
} }
public function testFetchDriverName():void { public function testFetchDriverName(): void {
$this->assertTrue(strlen(Driver::driverName()) > 0); $this->assertTrue(strlen(Driver::driverName()) > 0);
} }
public function testEnqueueFeeds():void { public function testEnqueueFeeds(): void {
$d = new Driver; $d = new Driver;
$this->assertSame(3, $d->queue(1, 2, 3)); $this->assertSame(3, $d->queue(1, 2, 3));
$this->assertSame(5, $d->queue(4, 5)); $this->assertSame(5, $d->queue(4, 5));
@ -36,7 +36,7 @@ class TestSerial extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame(1, $d->queue(5)); $this->assertSame(1, $d->queue(5));
} }
public function testRefreshFeeds():void { public function testRefreshFeeds(): void {
$d = new Driver; $d = new Driver;
$d->queue(1, 4, 3); $d->queue(1, 4, 3);
$this->assertSame(Arsse::$conf->serviceQueueWidth, $d->exec()); $this->assertSame(Arsse::$conf->serviceQueueWidth, $d->exec());

12
tests/cases/Service/TestService.php

@ -22,14 +22,14 @@ class TestService extends \JKingWeb\Arsse\Test\AbstractTest {
$this->srv = new Service(); $this->srv = new Service();
} }
public function testCheckIn():void { public function testCheckIn(): void {
$now = time(); $now = time();
$this->srv->checkIn(); $this->srv->checkIn();
\Phake::verify(Arsse::$db)->metaSet("service_last_checkin", \Phake::capture($then), "datetime"); \Phake::verify(Arsse::$db)->metaSet("service_last_checkin", \Phake::capture($then), "datetime");
$this->assertTime($now, $then); $this->assertTime($now, $then);
} }
public function testReportHavingCheckedIn():void { public function testReportHavingCheckedIn(): void {
// the mock's metaGet() returns null by default // the mock's metaGet() returns null by default
$this->assertFalse(Service::hasCheckedIn()); $this->assertFalse(Service::hasCheckedIn());
$interval = Arsse::$conf->serviceFrequency; $interval = Arsse::$conf->serviceFrequency;
@ -40,27 +40,27 @@ class TestService extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertFalse(Service::hasCheckedIn()); $this->assertFalse(Service::hasCheckedIn());
} }
public function testPerformPreCleanup():void { public function testPerformPreCleanup(): void {
$this->assertTrue(Service::cleanupPre()); $this->assertTrue(Service::cleanupPre());
\Phake::verify(Arsse::$db)->feedCleanup(); \Phake::verify(Arsse::$db)->feedCleanup();
\Phake::verify(Arsse::$db)->sessionCleanup(); \Phake::verify(Arsse::$db)->sessionCleanup();
} }
public function testPerformShortPostCleanup():void { public function testPerformShortPostCleanup(): void {
\Phake::when(Arsse::$db)->articleCleanup()->thenReturn(0); \Phake::when(Arsse::$db)->articleCleanup()->thenReturn(0);
$this->assertTrue(Service::cleanupPost()); $this->assertTrue(Service::cleanupPost());
\Phake::verify(Arsse::$db)->articleCleanup(); \Phake::verify(Arsse::$db)->articleCleanup();
\Phake::verify(Arsse::$db, \Phake::times(0))->driverMaintenance(); \Phake::verify(Arsse::$db, \Phake::times(0))->driverMaintenance();
} }
public function testPerformFullPostCleanup():void { public function testPerformFullPostCleanup(): void {
\Phake::when(Arsse::$db)->articleCleanup()->thenReturn(1); \Phake::when(Arsse::$db)->articleCleanup()->thenReturn(1);
$this->assertTrue(Service::cleanupPost()); $this->assertTrue(Service::cleanupPost());
\Phake::verify(Arsse::$db)->articleCleanup(); \Phake::verify(Arsse::$db)->articleCleanup();
\Phake::verify(Arsse::$db)->driverMaintenance(); \Phake::verify(Arsse::$db)->driverMaintenance();
} }
public function testRefreshFeeds():void { public function testRefreshFeeds(): void {
// set up mock database actions // set up mock database actions
\Phake::when(Arsse::$db)->metaSet->thenReturn(true); \Phake::when(Arsse::$db)->metaSet->thenReturn(true);
\Phake::when(Arsse::$db)->feedCleanup->thenReturn(true); \Phake::when(Arsse::$db)->feedCleanup->thenReturn(true);

8
tests/cases/Service/TestSubprocess.php

@ -18,16 +18,16 @@ class TestSubprocess extends \JKingWeb\Arsse\Test\AbstractTest {
self::setConf(); self::setConf();
} }
public function testConstruct():void { public function testConstruct(): void {
$this->assertTrue(Driver::requirementsMet()); $this->assertTrue(Driver::requirementsMet());
$this->assertInstanceOf(DriverInterface::class, new Driver); $this->assertInstanceOf(DriverInterface::class, new Driver);
} }
public function testFetchDriverName():void { public function testFetchDriverName(): void {
$this->assertTrue(strlen(Driver::driverName()) > 0); $this->assertTrue(strlen(Driver::driverName()) > 0);
} }
public function testEnqueueFeeds():void { public function testEnqueueFeeds(): void {
$d = new Driver; $d = new Driver;
$this->assertSame(3, $d->queue(1, 2, 3)); $this->assertSame(3, $d->queue(1, 2, 3));
$this->assertSame(5, $d->queue(4, 5)); $this->assertSame(5, $d->queue(4, 5));
@ -35,7 +35,7 @@ class TestSubprocess extends \JKingWeb\Arsse\Test\AbstractTest {
$this->assertSame(1, $d->queue(5)); $this->assertSame(1, $d->queue(5));
} }
public function testRefreshFeeds():void { public function testRefreshFeeds(): void {
$d = \Phake::partialMock(Driver::class); $d = \Phake::partialMock(Driver::class);
\Phake::when($d)->execCmd->thenReturnCallback(function(string $cmd) { \Phake::when($d)->execCmd->thenReturnCallback(function(string $cmd) {
// FIXME: Does this work in Windows? // FIXME: Does this work in Windows?

4
tests/cases/TestArsse.php

@ -22,7 +22,7 @@ class TestArsse extends \JKingWeb\Arsse\Test\AbstractTest {
self::clearData(); self::clearData();
} }
public function testLoadExistingData():void { public function testLoadExistingData(): void {
$lang = Arsse::$lang = \Phake::mock(Lang::class); $lang = Arsse::$lang = \Phake::mock(Lang::class);
$db = Arsse::$db = \Phake::mock(Database::class); $db = Arsse::$db = \Phake::mock(Database::class);
$user = Arsse::$user = \Phake::mock(User::class); $user = Arsse::$user = \Phake::mock(User::class);
@ -36,7 +36,7 @@ class TestArsse extends \JKingWeb\Arsse\Test\AbstractTest {
\Phake::verify($lang)->set("test"); \Phake::verify($lang)->set("test");
} }
public function testLoadNewData():void { public function testLoadNewData(): void {
if (!\JKingWeb\Arsse\Db\SQLite3\Driver::requirementsMet() && !\JKingWeb\Arsse\Db\SQLite3\PDODriver::requirementsMet()) { if (!\JKingWeb\Arsse\Db\SQLite3\Driver::requirementsMet() && !\JKingWeb\Arsse\Db\SQLite3\PDODriver::requirementsMet()) {
$this->markTestSkipped("A functional SQLite interface is required for this test"); $this->markTestSkipped("A functional SQLite interface is required for this test");
} }

22
tests/cases/User/TestInternal.php

@ -21,11 +21,11 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
\Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(\JKingWeb\Arsse\Db\Transaction::class)); \Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(\JKingWeb\Arsse\Db\Transaction::class));
} }
public function testConstruct():void { public function testConstruct(): void {
$this->assertInstanceOf(DriverInterface::class, new Driver); $this->assertInstanceOf(DriverInterface::class, new Driver);
} }
public function testFetchDriverName():void { public function testFetchDriverName(): void {
$this->assertTrue(strlen(Driver::driverName()) > 0); $this->assertTrue(strlen(Driver::driverName()) > 0);
} }
@ -33,7 +33,7 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
* @dataProvider provideAuthentication * @dataProvider provideAuthentication
* @group slow * @group slow
*/ */
public function testAuthenticateAUser(bool $authorized, string $user, $password, bool $exp):void { public function testAuthenticateAUser(bool $authorized, string $user, $password, bool $exp): void {
if ($authorized) { if ($authorized) {
\Phake::when(Arsse::$db)->userPasswordGet("john.doe@example.com")->thenReturn('$2y$10$1zbqRJhxM8uUjeSBPp4IhO90xrqK0XjEh9Z16iIYEFRV4U.zeAFom'); // hash of "secret" \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("jane.doe@example.com")->thenReturn('$2y$10$bK1ljXfTSyc2D.NYvT.Eq..OpehLRXVbglW.23ihVuyhgwJCd.7Im'); // hash of "superman"
@ -74,12 +74,12 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
]; ];
} }
public function testAuthorizeAnAction():void { public function testAuthorizeAnAction(): void {
\Phake::verifyNoFurtherInteraction(Arsse::$db); \Phake::verifyNoFurtherInteraction(Arsse::$db);
$this->assertTrue((new Driver)->authorize("someone", "something")); $this->assertTrue((new Driver)->authorize("someone", "something"));
} }
public function testListUsers():void { public function testListUsers(): void {
$john = "john.doe@example.com"; $john = "john.doe@example.com";
$jane = "jane.doe@example.com"; $jane = "jane.doe@example.com";
\Phake::when(Arsse::$db)->userList->thenReturn([$john, $jane])->thenReturn([$jane, $john]); \Phake::when(Arsse::$db)->userList->thenReturn([$john, $jane])->thenReturn([$jane, $john]);
@ -89,7 +89,7 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
\Phake::verify(Arsse::$db, \Phake::times(2))->userList; \Phake::verify(Arsse::$db, \Phake::times(2))->userList;
} }
public function testCheckThatAUserExists():void { public function testCheckThatAUserExists(): void {
$john = "john.doe@example.com"; $john = "john.doe@example.com";
$jane = "jane.doe@example.com"; $jane = "jane.doe@example.com";
\Phake::when(Arsse::$db)->userExists($john)->thenReturn(true); \Phake::when(Arsse::$db)->userExists($john)->thenReturn(true);
@ -101,7 +101,7 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
\Phake::verify(Arsse::$db)->userExists($jane); \Phake::verify(Arsse::$db)->userExists($jane);
} }
public function testAddAUser():void { public function testAddAUser(): void {
$john = "john.doe@example.com"; $john = "john.doe@example.com";
\Phake::when(Arsse::$db)->userAdd->thenReturnCallback(function($user, $pass) { \Phake::when(Arsse::$db)->userAdd->thenReturnCallback(function($user, $pass) {
return $pass; return $pass;
@ -114,7 +114,7 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
\Phake::verify(Arsse::$db)->userAdd; \Phake::verify(Arsse::$db)->userAdd;
} }
public function testRemoveAUser():void { public function testRemoveAUser(): void {
$john = "john.doe@example.com"; $john = "john.doe@example.com";
\Phake::when(Arsse::$db)->userRemove->thenReturn(true)->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist")); \Phake::when(Arsse::$db)->userRemove->thenReturn(true)->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist"));
$driver = new Driver; $driver = new Driver;
@ -128,21 +128,21 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
} }
} }
public function testSetAPassword():void { public function testSetAPassword(): void {
$john = "john.doe@example.com"; $john = "john.doe@example.com";
\Phake::verifyNoFurtherInteraction(Arsse::$db); \Phake::verifyNoFurtherInteraction(Arsse::$db);
$this->assertSame("superman", (new Driver)->userPasswordSet($john, "superman")); $this->assertSame("superman", (new Driver)->userPasswordSet($john, "superman"));
$this->assertSame(null, (new Driver)->userPasswordSet($john, null)); $this->assertSame(null, (new Driver)->userPasswordSet($john, null));
} }
public function testUnsetAPassword():void { public function testUnsetAPassword(): void {
$drv = \Phake::partialMock(Driver::class); $drv = \Phake::partialMock(Driver::class);
\Phake::when($drv)->userExists->thenReturn(true); \Phake::when($drv)->userExists->thenReturn(true);
\Phake::verifyNoFurtherInteraction(Arsse::$db); \Phake::verifyNoFurtherInteraction(Arsse::$db);
$this->assertTrue($drv->userPasswordUnset("john.doe@example.com")); $this->assertTrue($drv->userPasswordUnset("john.doe@example.com"));
} }
public function testUnsetAPasswordForAMssingUser():void { public function testUnsetAPasswordForAMssingUser(): void {
$drv = \Phake::partialMock(Driver::class); $drv = \Phake::partialMock(Driver::class);
\Phake::when($drv)->userExists->thenReturn(false); \Phake::when($drv)->userExists->thenReturn(false);
\Phake::verifyNoFurtherInteraction(Arsse::$db); \Phake::verifyNoFurtherInteraction(Arsse::$db);

22
tests/cases/User/TestUser.php

@ -24,12 +24,12 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
$this->drv = \Phake::mock(Driver::class); $this->drv = \Phake::mock(Driver::class);
} }
public function testConstruct():void { public function testConstruct(): void {
$this->assertInstanceOf(User::class, new User($this->drv)); $this->assertInstanceOf(User::class, new User($this->drv));
$this->assertInstanceOf(User::class, new User); $this->assertInstanceOf(User::class, new User);
} }
public function testConversionToString():void { public function testConversionToString(): void {
$u = new User; $u = new User;
$u->id = "john.doe@example.com"; $u->id = "john.doe@example.com";
$this->assertSame("john.doe@example.com", (string) $u); $this->assertSame("john.doe@example.com", (string) $u);
@ -38,7 +38,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideAuthentication */ /** @dataProvider provideAuthentication */
public function testAuthenticateAUser(bool $preAuth, string $user, string $password, bool $exp):void { public function testAuthenticateAUser(bool $preAuth, string $user, string $password, bool $exp): void {
Arsse::$conf->userPreAuth = $preAuth; Arsse::$conf->userPreAuth = $preAuth;
\Phake::when($this->drv)->auth->thenReturn(false); \Phake::when($this->drv)->auth->thenReturn(false);
\Phake::when($this->drv)->auth("john.doe@example.com", "secret")->thenReturn(true); \Phake::when($this->drv)->auth("john.doe@example.com", "secret")->thenReturn(true);
@ -69,7 +69,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideUserList */ /** @dataProvider provideUserList */
public function testListUsers(bool $authorized, $exp):void { public function testListUsers(bool $authorized, $exp): void {
$u = new User($this->drv); $u = new User($this->drv);
\Phake::when($this->drv)->authorize->thenReturn($authorized); \Phake::when($this->drv)->authorize->thenReturn($authorized);
\Phake::when($this->drv)->userList->thenReturn(["john.doe@example.com", "jane.doe@example.com"]); \Phake::when($this->drv)->userList->thenReturn(["john.doe@example.com", "jane.doe@example.com"]);
@ -89,7 +89,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideExistence */ /** @dataProvider provideExistence */
public function testCheckThatAUserExists(bool $authorized, string $user, $exp):void { public function testCheckThatAUserExists(bool $authorized, string $user, $exp): void {
$u = new User($this->drv); $u = new User($this->drv);
\Phake::when($this->drv)->authorize->thenReturn($authorized); \Phake::when($this->drv)->authorize->thenReturn($authorized);
\Phake::when($this->drv)->userExists("john.doe@example.com")->thenReturn(true); \Phake::when($this->drv)->userExists("john.doe@example.com")->thenReturn(true);
@ -112,7 +112,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideAdditions */ /** @dataProvider provideAdditions */
public function testAddAUser(bool $authorized, string $user, $password, $exp):void { public function testAddAUser(bool $authorized, string $user, $password, $exp): void {
$u = new User($this->drv); $u = new User($this->drv);
\Phake::when($this->drv)->authorize->thenReturn($authorized); \Phake::when($this->drv)->authorize->thenReturn($authorized);
\Phake::when($this->drv)->userAdd("john.doe@example.com", $this->anything())->thenThrow(new \JKingWeb\Arsse\User\Exception("alreadyExists")); \Phake::when($this->drv)->userAdd("john.doe@example.com", $this->anything())->thenThrow(new \JKingWeb\Arsse\User\Exception("alreadyExists"));
@ -130,7 +130,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideAdditions */ /** @dataProvider provideAdditions */
public function testAddAUserWithARandomPassword(bool $authorized, string $user, $password, $exp):void { public function testAddAUserWithARandomPassword(bool $authorized, string $user, $password, $exp): void {
$u = \Phake::partialMock(User::class, $this->drv); $u = \Phake::partialMock(User::class, $this->drv);
\Phake::when($this->drv)->authorize->thenReturn($authorized); \Phake::when($this->drv)->authorize->thenReturn($authorized);
\Phake::when($this->drv)->userAdd($this->anything(), $this->isNull())->thenReturn(null); \Phake::when($this->drv)->userAdd($this->anything(), $this->isNull())->thenReturn(null);
@ -172,7 +172,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider provideRemovals */ /** @dataProvider provideRemovals */
public function testRemoveAUser(bool $authorized, string $user, bool $exists, $exp):void { public function testRemoveAUser(bool $authorized, string $user, bool $exists, $exp): void {
$u = new User($this->drv); $u = new User($this->drv);
\Phake::when($this->drv)->authorize->thenReturn($authorized); \Phake::when($this->drv)->authorize->thenReturn($authorized);
\Phake::when($this->drv)->userRemove("john.doe@example.com")->thenReturn(true); \Phake::when($this->drv)->userRemove("john.doe@example.com")->thenReturn(true);
@ -210,7 +210,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider providePasswordChanges */ /** @dataProvider providePasswordChanges */
public function testChangeAPassword(bool $authorized, string $user, $password, bool $exists, $exp):void { public function testChangeAPassword(bool $authorized, string $user, $password, bool $exists, $exp): void {
$u = new User($this->drv); $u = new User($this->drv);
\Phake::when($this->drv)->authorize->thenReturn($authorized); \Phake::when($this->drv)->authorize->thenReturn($authorized);
\Phake::when($this->drv)->userPasswordSet("john.doe@example.com", $this->anything(), $this->anything())->thenReturnCallback(function($user, $pass, $old) { \Phake::when($this->drv)->userPasswordSet("john.doe@example.com", $this->anything(), $this->anything())->thenReturnCallback(function($user, $pass, $old) {
@ -237,7 +237,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider providePasswordChanges */ /** @dataProvider providePasswordChanges */
public function testChangeAPasswordToARandomPassword(bool $authorized, string $user, $password, bool $exists, $exp):void { public function testChangeAPasswordToARandomPassword(bool $authorized, string $user, $password, bool $exists, $exp): void {
$u = \Phake::partialMock(User::class, $this->drv); $u = \Phake::partialMock(User::class, $this->drv);
\Phake::when($this->drv)->authorize->thenReturn($authorized); \Phake::when($this->drv)->authorize->thenReturn($authorized);
\Phake::when($this->drv)->userPasswordSet($this->anything(), $this->isNull(), $this->anything())->thenReturn(null); \Phake::when($this->drv)->userPasswordSet($this->anything(), $this->isNull(), $this->anything())->thenReturn(null);
@ -289,7 +289,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
} }
/** @dataProvider providePasswordClearings */ /** @dataProvider providePasswordClearings */
public function testClearAPassword(bool $authorized, bool $exists, string $user, $exp):void { public function testClearAPassword(bool $authorized, bool $exists, string $user, $exp): void {
\Phake::when($this->drv)->authorize->thenReturn($authorized); \Phake::when($this->drv)->authorize->thenReturn($authorized);
\Phake::when($this->drv)->userPasswordUnset->thenReturn(true); \Phake::when($this->drv)->userPasswordUnset->thenReturn(true);
\Phake::when($this->drv)->userPasswordUnset("jane.doe@example.net", null)->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist")); \Phake::when($this->drv)->userPasswordUnset("jane.doe@example.net", null)->thenThrow(new \JKingWeb\Arsse\User\Exception("doesNotExist"));

Loading…
Cancel
Save