mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 21:22:40 +00:00
Start on replacing Phake with Phony
This commit is contained in:
parent
9b369d902f
commit
2348786a92
41 changed files with 574 additions and 487 deletions
|
@ -12,7 +12,7 @@ const DOCROOT = BASE."tests".DIRECTORY_SEPARATOR."docroot".DIRECTORY_SEPARATOR;
|
|||
ini_set("memory_limit", "-1");
|
||||
ini_set("zend.assertions", "1");
|
||||
ini_set("assert.exception", "true");
|
||||
error_reporting(\E_ALL);
|
||||
error_reporting(\E_ALL ^ \E_DEPRECATED);
|
||||
require_once BASE."vendor".DIRECTORY_SEPARATOR."autoload.php";
|
||||
|
||||
if (function_exists("xdebug_set_filter")) {
|
||||
|
|
|
@ -20,13 +20,16 @@ use JKingWeb\Arsse\ImportExport\OPML;
|
|||
/** @covers \JKingWeb\Arsse\CLI */
|
||||
class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
$this->cli = \Phake::partialMock(CLI::class);
|
||||
\Phake::when($this->cli)->logError->thenReturn(null);
|
||||
\Phake::when($this->cli)->loadConf->thenReturn(true);
|
||||
parent::setUp();
|
||||
$this->cli = $this->partialMock(CLI::class);
|
||||
$this->cli->logError->returns(null);
|
||||
$this->cli->loadConf->returns(true);
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
}
|
||||
|
||||
public function assertConsole(CLI $cli, string $command, int $exitStatus, string $output = "", bool $pattern = false): void {
|
||||
public function assertConsole(string $command, int $exitStatus, string $output = "", bool $pattern = false): void {
|
||||
Arsse::$obj = $this->objMock->get();
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
$argv = \Clue\Arguments\split($command);
|
||||
$output = strlen($output) ? $output.\PHP_EOL : "";
|
||||
if ($pattern) {
|
||||
|
@ -34,18 +37,18 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
} else {
|
||||
$this->expectOutputString($output);
|
||||
}
|
||||
$this->assertSame($exitStatus, $cli->dispatch($argv));
|
||||
$this->assertSame($exitStatus, $this->cli->get()->dispatch($argv));
|
||||
}
|
||||
|
||||
public function testPrintVersion(): void {
|
||||
$this->assertConsole($this->cli, "arsse.php --version", 0, Arsse::VERSION);
|
||||
\Phake::verify($this->cli, \Phake::times(0))->loadConf;
|
||||
$this->assertConsole("arsse.php --version", 0, Arsse::VERSION);
|
||||
$this->cli->loadConf->never()->called();
|
||||
}
|
||||
|
||||
/** @dataProvider provideHelpText */
|
||||
public function testPrintHelp(string $cmd, string $name): void {
|
||||
$this->assertConsole($this->cli, $cmd, 0, str_replace("arsse.php", $name, CLI::USAGE));
|
||||
\Phake::verify($this->cli, \Phake::times(0))->loadConf;
|
||||
$this->assertConsole($cmd, 0, str_replace("arsse.php", $name, CLI::USAGE));
|
||||
$this->cli->loadConf->never()->called();
|
||||
}
|
||||
|
||||
public function provideHelpText(): iterable {
|
||||
|
@ -60,31 +63,30 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testStartTheDaemon(): void {
|
||||
$srv = \Phake::mock(Service::class);
|
||||
\Phake::when(Arsse::$obj)->get(Service::class)->thenReturn($srv);
|
||||
\Phake::when($srv)->watch->thenReturn(new \DateTimeImmutable);
|
||||
$this->assertConsole($this->cli, "arsse.php daemon", 0);
|
||||
\Phake::verify($this->cli)->loadConf;
|
||||
\Phake::verify($srv)->watch(true);
|
||||
$srv = $this->mock(Service::class);
|
||||
$srv->watch->returns(new \DateTimeImmutable);
|
||||
$this->objMock->get->with(Service::class)->returns($srv->get());
|
||||
$this->assertConsole("arsse.php daemon", 0);
|
||||
$this->cli->loadConf->called();
|
||||
$srv->watch->calledWith(true);
|
||||
}
|
||||
|
||||
public function testRefreshAllFeeds(): void {
|
||||
$srv = \Phake::mock(Service::class);
|
||||
\Phake::when(Arsse::$obj)->get(Service::class)->thenReturn($srv);
|
||||
\Phake::when($srv)->watch->thenReturn(new \DateTimeImmutable);
|
||||
$this->assertConsole($this->cli, "arsse.php feed refresh-all", 0);
|
||||
\Phake::verify($this->cli)->loadConf;
|
||||
\Phake::verify($srv)->watch(false);
|
||||
$srv = $this->mock(Service::class);
|
||||
$srv->watch->returns(new \DateTimeImmutable);
|
||||
$this->objMock->get->with(Service::class)->returns($srv->get());
|
||||
$this->assertConsole("arsse.php feed refresh-all", 0);
|
||||
$this->cli->loadConf->called();
|
||||
$srv->watch->calledWith(false);
|
||||
}
|
||||
|
||||
/** @dataProvider provideFeedUpdates */
|
||||
public function testRefreshAFeed(string $cmd, int $exitStatus, string $output): void {
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
\Phake::when(Arsse::$db)->feedUpdate(1, true)->thenReturn(true);
|
||||
\Phake::when(Arsse::$db)->feedUpdate(2, true)->thenThrow(new \JKingWeb\Arsse\Feed\Exception("", ['url' => "http://example.com/"], $this->mockGuzzleException(ClientException::class, "", 404)));
|
||||
$this->assertConsole($this->cli, $cmd, $exitStatus, $output);
|
||||
\Phake::verify($this->cli)->loadConf;
|
||||
\Phake::verify(Arsse::$db)->feedUpdate;
|
||||
$this->dbMock->feedUpdate->with(1, true)->returns(true);
|
||||
$this->dbMock->feedUpdate->with(2, true)->throws(new \JKingWeb\Arsse\Feed\Exception("", ['url' => "http://example.com/"], $this->mockGuzzleException(ClientException::class, "", 404)));
|
||||
$this->assertConsole($cmd, $exitStatus, $output);
|
||||
$this->cli->loadConf->called();
|
||||
$this->dbMock->feedUpdate->called();
|
||||
}
|
||||
|
||||
public function provideFeedUpdates(): iterable {
|
||||
|
@ -96,14 +98,14 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
/** @dataProvider provideDefaultConfigurationSaves */
|
||||
public function testSaveTheDefaultConfiguration(string $cmd, int $exitStatus, string $file): void {
|
||||
$conf = \Phake::mock(Conf::class);
|
||||
\Phake::when(Arsse::$obj)->get(Conf::class)->thenReturn($conf);
|
||||
\Phake::when($conf)->exportFile("php://output", true)->thenReturn(true);
|
||||
\Phake::when($conf)->exportFile("good.conf", true)->thenReturn(true);
|
||||
\Phake::when($conf)->exportFile("bad.conf", true)->thenThrow(new \JKingWeb\Arsse\Conf\Exception("fileUnwritable"));
|
||||
$this->assertConsole($this->cli, $cmd, $exitStatus);
|
||||
\Phake::verify($this->cli, \Phake::times(0))->loadConf;
|
||||
\Phake::verify($conf)->exportFile($file, true);
|
||||
$conf = $this->mock(Conf::class);
|
||||
$conf->exportFile->with("php://output", true)->returns(true);
|
||||
$conf->exportFile->with("good.conf", true)->returns(true);
|
||||
$conf->exportFile->with("bad.conf", true)->throws(new \JKingWeb\Arsse\Conf\Exception("fileUnwritable"));
|
||||
$this->objMock->get->with(Conf::class)->returns($conf->get());
|
||||
$this->assertConsole($cmd, $exitStatus);
|
||||
$this->cli->loadConf->never()->called();
|
||||
$conf->exportFile->calledWith($file, true);
|
||||
}
|
||||
|
||||
public function provideDefaultConfigurationSaves(): iterable {
|
||||
|
@ -120,7 +122,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
// 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->method("list")->willReturn($list);
|
||||
$this->assertConsole($this->cli, $cmd, $exitStatus, $output);
|
||||
$this->assertConsole($cmd, $exitStatus, $output);
|
||||
}
|
||||
|
||||
public function provideUserList(): iterable {
|
||||
|
@ -146,7 +148,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
return is_null($pass) ? "random password" : $pass;
|
||||
}
|
||||
}));
|
||||
$this->assertConsole($this->cli, $cmd, $exitStatus, $output);
|
||||
$this->assertConsole($cmd, $exitStatus, $output);
|
||||
}
|
||||
|
||||
public function provideUserAdditions(): iterable {
|
||||
|
@ -163,7 +165,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
Arsse::$user->method("propertiesSet")->willReturn([]);
|
||||
Arsse::$user->expects($this->exactly(1))->method("add")->with("jane.doe@example.com", null);
|
||||
Arsse::$user->expects($this->exactly(1))->method("propertiesSet")->with("jane.doe@example.com", ['admin' => true]);
|
||||
$this->assertConsole($this->cli, "arsse.php user add jane.doe@example.com --admin", 0, "random password");
|
||||
$this->assertConsole("arsse.php user add jane.doe@example.com --admin", 0, "random password");
|
||||
}
|
||||
|
||||
/** @dataProvider provideUserAuthentication */
|
||||
|
@ -176,12 +178,12 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
($user === "jane.doe@example.com" && $pass === "superman")
|
||||
;
|
||||
}));
|
||||
$fever = \Phake::mock(FeverUser::class);
|
||||
\Phake::when(Arsse::$obj)->get(FeverUser::class)->thenReturn($fever);
|
||||
\Phake::when($fever)->authenticate->thenReturn(false);
|
||||
\Phake::when($fever)->authenticate("john.doe@example.com", "ashalla")->thenReturn(true);
|
||||
\Phake::when($fever)->authenticate("jane.doe@example.com", "thx1138")->thenReturn(true);
|
||||
$this->assertConsole($this->cli, $cmd, $exitStatus, $output);
|
||||
$fever = $this->mock(FeverUser::class);
|
||||
$fever->authenticate->returns(false);
|
||||
$fever->authenticate->with("john.doe@example.com", "ashalla")->returns(true);
|
||||
$fever->authenticate->with("jane.doe@example.com", "thx1138")->returns(true);
|
||||
$this->objMock->get->with(FeverUser::class)->returns($fever->get());
|
||||
$this->assertConsole($cmd, $exitStatus, $output);
|
||||
}
|
||||
|
||||
public function provideUserAuthentication(): iterable {
|
||||
|
@ -210,7 +212,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
throw new \JKingWeb\Arsse\User\ExceptionConflict("doesNotExist");
|
||||
}));
|
||||
$this->assertConsole($this->cli, $cmd, $exitStatus, $output);
|
||||
$this->assertConsole($cmd, $exitStatus, $output);
|
||||
}
|
||||
|
||||
public function provideUserRemovals(): iterable {
|
||||
|
@ -233,10 +235,10 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
// 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->method("passwordSet")->will($this->returnCallback($passwordChange));
|
||||
$fever = \Phake::mock(FeverUser::class);
|
||||
\Phake::when(Arsse::$obj)->get(FeverUser::class)->thenReturn($fever);
|
||||
\Phake::when($fever)->register->thenReturnCallback($passwordChange);
|
||||
$this->assertConsole($this->cli, $cmd, $exitStatus, $output);
|
||||
$fever = $this->mock(FeverUser::class);
|
||||
$fever->register->does($passwordChange);
|
||||
$this->objMock->get->with(FeverUser::class)->returns($fever->get());
|
||||
$this->assertConsole($cmd, $exitStatus, $output);
|
||||
}
|
||||
|
||||
public function provideUserPasswordChanges(): iterable {
|
||||
|
@ -263,10 +265,10 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
// 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->method("passwordUnset")->will($this->returnCallback($passwordClear));
|
||||
$fever = \Phake::mock(FeverUser::class);
|
||||
\Phake::when(Arsse::$obj)->get(FeverUser::class)->thenReturn($fever);
|
||||
\Phake::when($fever)->unregister->thenReturnCallback($passwordClear);
|
||||
$this->assertConsole($this->cli, $cmd, $exitStatus, $output);
|
||||
$fever = $this->mock(FeverUser::class);
|
||||
$fever->unregister->does($passwordClear);
|
||||
$this->objMock->get->with(FeverUser::class)->returns($fever->get());
|
||||
$this->assertConsole($cmd, $exitStatus, $output);
|
||||
}
|
||||
|
||||
public function provideUserPasswordClearings(): iterable {
|
||||
|
@ -280,14 +282,14 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
/** @dataProvider provideOpmlExports */
|
||||
public function testExportToOpml(string $cmd, int $exitStatus, string $file, string $user, bool $flat): void {
|
||||
$opml = \Phake::mock(OPML::class);
|
||||
\Phake::when(Arsse::$obj)->get(OPML::class)->thenReturn($opml);
|
||||
\Phake::when($opml)->exportFile("php://output", $user, $flat)->thenReturn(true);
|
||||
\Phake::when($opml)->exportFile("good.opml", $user, $flat)->thenReturn(true);
|
||||
\Phake::when($opml)->exportFile("bad.opml", $user, $flat)->thenThrow(new \JKingWeb\Arsse\ImportExport\Exception("fileUnwritable"));
|
||||
$this->assertConsole($this->cli, $cmd, $exitStatus);
|
||||
\Phake::verify($this->cli)->loadConf;
|
||||
\Phake::verify($opml)->exportFile($file, $user, $flat);
|
||||
$opml = $this->mock(OPML::class);
|
||||
$opml->exportFile->with("php://output", $user, $flat)->returns(true);
|
||||
$opml->exportFile->with("good.opml", $user, $flat)->returns(true);
|
||||
$opml->exportFile->with("bad.opml", $user, $flat)->throws(new \JKingWeb\Arsse\ImportExport\Exception("fileUnwritable"));
|
||||
$this->objMock->get->with(OPML::class)->returns($opml->get());
|
||||
$this->assertConsole($cmd, $exitStatus);
|
||||
$this->cli->loadConf->called();
|
||||
$opml->exportFile->calledWith($file, $user, $flat);
|
||||
}
|
||||
|
||||
public function provideOpmlExports(): iterable {
|
||||
|
@ -321,14 +323,14 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
/** @dataProvider provideOpmlImports */
|
||||
public function testImportFromOpml(string $cmd, int $exitStatus, string $file, string $user, bool $flat, bool $replace): void {
|
||||
$opml = \Phake::mock(OPML::class);
|
||||
\Phake::when(Arsse::$obj)->get(OPML::class)->thenReturn($opml);
|
||||
\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("bad.opml", $user, $flat, $replace)->thenThrow(new \JKingWeb\Arsse\ImportExport\Exception("fileUnreadable"));
|
||||
$this->assertConsole($this->cli, $cmd, $exitStatus);
|
||||
\Phake::verify($this->cli)->loadConf;
|
||||
\Phake::verify($opml)->importFile($file, $user, $flat, $replace);
|
||||
$opml = $this->mock(OPML::class);
|
||||
$opml->importFile->with("php://input", $user, $flat, $replace)->returns(true);
|
||||
$opml->importFile->with("good.opml", $user, $flat, $replace)->returns(true);
|
||||
$opml->importFile->with("bad.opml", $user, $flat, $replace)->throws(new \JKingWeb\Arsse\ImportExport\Exception("fileUnreadable"));
|
||||
$this->objMock->get->with(OPML::class)->returns($opml->get());
|
||||
$this->assertConsole($cmd, $exitStatus);
|
||||
$this->cli->loadConf->called();
|
||||
$opml->importFile->calledWith($file, $user, $flat, $replace);
|
||||
}
|
||||
|
||||
public function provideOpmlImports(): iterable {
|
||||
|
@ -400,7 +402,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
Arsse::$user = $this->createMock(User::class);
|
||||
Arsse::$user->method("propertiesGet")->willReturn($data);
|
||||
Arsse::$user->expects($this->once())->method("propertiesGet")->with("john.doe@example.com", true);
|
||||
$this->assertConsole($this->cli, "arsse.php user show john.doe@example.com", 0, $exp);
|
||||
$this->assertConsole("arsse.php user show john.doe@example.com", 0, $exp);
|
||||
}
|
||||
|
||||
/** @dataProvider provideMetadataChanges */
|
||||
|
@ -408,7 +410,7 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
Arsse::$user = $this->createMock(User::class);
|
||||
Arsse::$user->method("propertiesSet")->willReturn($out);
|
||||
Arsse::$user->expects($this->once())->method("propertiesSet")->with($user, $in);
|
||||
$this->assertConsole($this->cli, $cmd, $exp, "");
|
||||
$this->assertConsole($cmd, $exp, "");
|
||||
}
|
||||
|
||||
public function provideMetadataChanges(): iterable {
|
||||
|
@ -433,40 +435,38 @@ class TestCLI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
"TOKEN 2 Eek",
|
||||
"TOKEN 1 Ook",
|
||||
]);
|
||||
$t = \Phake::mock(MinifluxToken::class);
|
||||
\Phake::when(Arsse::$obj)->get(MinifluxToken::class)->thenReturn($t);
|
||||
\Phake::when($t)->tokenList->thenReturn($data);
|
||||
$this->assertConsole($this->cli, "arsse.php token list john", 0, $exp);
|
||||
\Phake::verify($t)->tokenList("john");
|
||||
$t = $this->mock(MinifluxToken::class);
|
||||
$t->tokenList->returns($data);
|
||||
$this->objMock->get->with(MinifluxToken::class)->returns($t->get());
|
||||
$this->assertConsole("arsse.php token list john", 0, $exp);
|
||||
$t->tokenList->calledWith("john");
|
||||
}
|
||||
|
||||
public function testCreateToken(): void {
|
||||
$t = \Phake::mock(MinifluxToken::class);
|
||||
\Phake::when(Arsse::$obj)->get(MinifluxToken::class)->thenReturn($t);
|
||||
\Phake::when($t)->tokenGenerate->thenReturn("RANDOM TOKEN");
|
||||
$this->assertConsole($this->cli, "arse.php token create jane", 0, "RANDOM TOKEN");
|
||||
\Phake::verify($t)->tokenGenerate("jane", null);
|
||||
$t = $this->mock(MinifluxToken::class);
|
||||
$t->tokenGenerate->returns("RANDOM TOKEN");
|
||||
$this->objMock->get->with(MinifluxToken::class)->returns($t->get());
|
||||
$this->assertConsole("arse.php token create jane", 0, "RANDOM TOKEN");
|
||||
$t->tokenGenerate->calledWith("jane", null);
|
||||
}
|
||||
|
||||
public function testCreateTokenWithLabel(): void {
|
||||
$t = \Phake::mock(MinifluxToken::class);
|
||||
\Phake::when(Arsse::$obj)->get(MinifluxToken::class)->thenReturn($t);
|
||||
\Phake::when($t)->tokenGenerate->thenReturn("RANDOM TOKEN");
|
||||
$this->assertConsole($this->cli, "arse.php token create jane Ook", 0, "RANDOM TOKEN");
|
||||
\Phake::verify($t)->tokenGenerate("jane", "Ook");
|
||||
$t = $this->mock(MinifluxToken::class);
|
||||
$t->tokenGenerate->returns("RANDOM TOKEN");
|
||||
$this->objMock->get->with(MinifluxToken::class)->returns($t->get());
|
||||
$this->assertConsole("arse.php token create jane Ook", 0, "RANDOM TOKEN");
|
||||
$t->tokenGenerate->calledWith("jane", "Ook");
|
||||
}
|
||||
|
||||
public function testRevokeAToken(): void {
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
\Phake::when(Arsse::$db)->tokenRevoke->thenReturn(true);
|
||||
$this->assertConsole($this->cli, "arse.php token revoke jane TOKEN_ID", 0);
|
||||
\Phake::verify(Arsse::$db)->tokenRevoke("jane", "miniflux.login", "TOKEN_ID");
|
||||
$this->dbMock->tokenRevoke->returns(true);
|
||||
$this->assertConsole("arse.php token revoke jane TOKEN_ID", 0);
|
||||
$this->dbMock->tokenRevoke->calledWith("jane", "miniflux.login", "TOKEN_ID");
|
||||
}
|
||||
|
||||
public function testRevokeAllTokens(): void {
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
\Phake::when(Arsse::$db)->tokenRevoke->thenReturn(true);
|
||||
$this->assertConsole($this->cli, "arse.php token revoke jane", 0);
|
||||
\Phake::verify(Arsse::$db)->tokenRevoke("jane", "miniflux.login", null);
|
||||
$this->dbMock->tokenRevoke->returns(true);
|
||||
$this->assertConsole("arse.php token revoke jane", 0);
|
||||
$this->dbMock->tokenRevoke->calledWith("jane", "miniflux.login", null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public static $path;
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::$vfs = vfsStream::setup("root", null, [
|
||||
'confGood' => '<?php return Array("lang" => "xx");',
|
||||
'confNotArray' => '<?php return 0;',
|
||||
|
@ -35,7 +35,7 @@ class TestConf extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function tearDown(): void {
|
||||
self::$path = null;
|
||||
self::$vfs = null;
|
||||
self::clearData();
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testLoadDefaultValues(): void {
|
||||
|
|
|
@ -73,7 +73,8 @@ abstract class AbstractTest extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
Arsse::$db = new Database(static::$drv);
|
||||
Arsse::$db->driverSchemaUpdate();
|
||||
// create a mock user manager
|
||||
Arsse::$user = \Phake::mock(User::class);
|
||||
$this->userMock = $this->mock(User::class);
|
||||
Arsse::$user = $this->userMock->get();
|
||||
// call the series-specific setup method
|
||||
$setUp = "setUp".$this->series;
|
||||
$this->$setUp();
|
||||
|
|
|
@ -192,8 +192,6 @@ trait SeriesSubscription {
|
|||
],
|
||||
],
|
||||
];
|
||||
// initialize a partial mock of the Database object to later manipulate the feedUpdate method
|
||||
Arsse::$db = \Phake::partialMock(Database::class, static::$drv);
|
||||
$this->user = "john.doe@example.com";
|
||||
}
|
||||
|
||||
|
@ -204,9 +202,11 @@ trait SeriesSubscription {
|
|||
public function testAddASubscriptionToAnExistingFeed(): void {
|
||||
$url = "http://example.com/feed1";
|
||||
$subID = $this->nextID("arsse_subscriptions");
|
||||
\Phake::when(Arsse::$db)->feedUpdate->thenReturn(true);
|
||||
$db = $this->partialMock(Database::class, static::$drv);
|
||||
$db->feedUpdate->returns(true);
|
||||
Arsse::$db = $db->get();
|
||||
$this->assertSame($subID, Arsse::$db->subscriptionAdd($this->user, $url));
|
||||
\Phake::verify(Arsse::$db, \Phake::times(0))->feedUpdate(1, true);
|
||||
$db->feedUpdate->never()->called();
|
||||
$state = $this->primeExpectations($this->data, [
|
||||
'arsse_feeds' => ['id','url','username','password'],
|
||||
'arsse_subscriptions' => ['id','owner','feed'],
|
||||
|
@ -219,9 +219,11 @@ trait SeriesSubscription {
|
|||
$url = "http://example.org/feed1";
|
||||
$feedID = $this->nextID("arsse_feeds");
|
||||
$subID = $this->nextID("arsse_subscriptions");
|
||||
\Phake::when(Arsse::$db)->feedUpdate->thenReturn(true);
|
||||
$db = $this->partialMock(Database::class, static::$drv);
|
||||
$db->feedUpdate->returns(true);
|
||||
Arsse::$db = $db->get();
|
||||
$this->assertSame($subID, Arsse::$db->subscriptionAdd($this->user, $url, "", "", false));
|
||||
\Phake::verify(Arsse::$db)->feedUpdate($feedID, true, false);
|
||||
$db->feedUpdate->calledWith($feedID, true, false);
|
||||
$state = $this->primeExpectations($this->data, [
|
||||
'arsse_feeds' => ['id','url','username','password'],
|
||||
'arsse_subscriptions' => ['id','owner','feed'],
|
||||
|
@ -236,9 +238,11 @@ trait SeriesSubscription {
|
|||
$discovered = "http://localhost:8000/Feed/Discovery/Feed";
|
||||
$feedID = $this->nextID("arsse_feeds");
|
||||
$subID = $this->nextID("arsse_subscriptions");
|
||||
\Phake::when(Arsse::$db)->feedUpdate->thenReturn(true);
|
||||
$db = $this->partialMock(Database::class, static::$drv);
|
||||
$db->feedUpdate->returns(true);
|
||||
Arsse::$db = $db->get();
|
||||
$this->assertSame($subID, Arsse::$db->subscriptionAdd($this->user, $url, "", "", true));
|
||||
\Phake::verify(Arsse::$db)->feedUpdate($feedID, true, false);
|
||||
$db->feedUpdate->calledWith($feedID, true, false);
|
||||
$state = $this->primeExpectations($this->data, [
|
||||
'arsse_feeds' => ['id','url','username','password'],
|
||||
'arsse_subscriptions' => ['id','owner','feed'],
|
||||
|
@ -251,12 +255,14 @@ trait SeriesSubscription {
|
|||
public function testAddASubscriptionToAnInvalidFeed(): void {
|
||||
$url = "http://example.org/feed1";
|
||||
$feedID = $this->nextID("arsse_feeds");
|
||||
\Phake::when(Arsse::$db)->feedUpdate->thenThrow(new FeedException("", ['url' => $url], $this->mockGuzzleException(ClientException::class, "", 404)));
|
||||
$db = $this->partialMock(Database::class, static::$drv);
|
||||
$db->feedUpdate->throws(new FeedException("", ['url' => $url], $this->mockGuzzleException(ClientException::class, "", 404)));
|
||||
Arsse::$db = $db->get();
|
||||
$this->assertException("invalidUrl", "Feed");
|
||||
try {
|
||||
Arsse::$db->subscriptionAdd($this->user, $url, "", "", false);
|
||||
} finally {
|
||||
\Phake::verify(Arsse::$db)->feedUpdate($feedID, true, false);
|
||||
$db->feedUpdate->calledWith($feedID, true, false);
|
||||
$state = $this->primeExpectations($this->data, [
|
||||
'arsse_feeds' => ['id','url','username','password'],
|
||||
'arsse_subscriptions' => ['id','owner','feed'],
|
||||
|
|
|
@ -13,10 +13,10 @@ class TestDatabase extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
protected $db = null;
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
try {
|
||||
$this->db = \Phake::makeVisible(\Phake::partialMock(Database::class));
|
||||
$this->db = new Database;
|
||||
} catch (\JKingWeb\Arsse\Db\Exception $e) {
|
||||
$this->markTestSkipped("SQLite 3 database driver not available");
|
||||
}
|
||||
|
@ -24,14 +24,20 @@ class TestDatabase extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function tearDown(): void {
|
||||
$this->db = null;
|
||||
self::clearData();
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
protected function invoke(string $method, ...$arg) {
|
||||
$m = new \ReflectionMethod($this->db, $method);
|
||||
$m->setAccessible(true);
|
||||
return $m->invoke($this->db, ...$arg);
|
||||
}
|
||||
|
||||
/** @dataProvider provideInClauses */
|
||||
public function testGenerateInClause(string $clause, array $values, array $inV, string $inT): void {
|
||||
$types = array_fill(0, sizeof($values), $inT);
|
||||
$exp = [$clause, $types, $values];
|
||||
$this->assertSame($exp, $this->db->generateIn($inV, $inT));
|
||||
$this->assertSame($exp, $this->invoke("generateIn", $inV, $inT));
|
||||
}
|
||||
|
||||
public function provideInClauses(): iterable {
|
||||
|
@ -66,7 +72,7 @@ class TestDatabase extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
// this is not an exhaustive test; integration tests already cover the ins and outs of the functionality
|
||||
$types = array_fill(0, sizeof($values), "str");
|
||||
$exp = [$clause, $types, $values];
|
||||
$this->assertSame($exp, $this->db->generateSearch($inV, $inC, $inAny));
|
||||
$this->assertSame($exp, $this->invoke("generateSearch", $inV, $inC, $inAny));
|
||||
}
|
||||
|
||||
public function provideSearchClauses(): iterable {
|
||||
|
|
|
@ -31,7 +31,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf(static::$conf);
|
||||
if (!static::$interface) {
|
||||
$this->markTestSkipped(static::$implementation." database driver not available");
|
||||
|
@ -48,7 +48,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function tearDown(): void {
|
||||
// deconstruct the driver
|
||||
unset($this->drv);
|
||||
self::clearData();
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass(): void {
|
||||
|
@ -57,7 +57,7 @@ abstract class BaseDriver extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
static::dbRaze(static::$interface);
|
||||
}
|
||||
static::$interface = null;
|
||||
self::clearData();
|
||||
self::clearData(true);
|
||||
}
|
||||
|
||||
protected function exec($q): bool {
|
||||
|
|
|
@ -25,7 +25,7 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
if (!static::$interface) {
|
||||
$this->markTestSkipped(static::$implementation." database driver not available");
|
||||
|
@ -35,17 +35,13 @@ abstract class BaseResult extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->resultClass = static::$dbResultClass;
|
||||
}
|
||||
|
||||
public function tearDown(): void {
|
||||
self::clearData();
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass(): void {
|
||||
if (static::$interface) {
|
||||
// completely clear the database
|
||||
static::dbRaze(static::$interface);
|
||||
}
|
||||
static::$interface = null;
|
||||
self::clearData();
|
||||
self::clearData(true);
|
||||
}
|
||||
|
||||
public function testConstructResult(): void {
|
||||
|
|
|
@ -23,7 +23,7 @@ abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
if (!static::$interface) {
|
||||
$this->markTestSkipped(static::$implementation." database driver not available");
|
||||
|
@ -33,17 +33,13 @@ abstract class BaseStatement extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->statementClass = static::$dbStatementClass;
|
||||
}
|
||||
|
||||
public function tearDown(): void {
|
||||
self::clearData();
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass(): void {
|
||||
if (static::$interface) {
|
||||
// completely clear the database
|
||||
static::dbRaze(static::$interface);
|
||||
}
|
||||
static::$interface = null;
|
||||
self::clearData();
|
||||
self::clearData(true);
|
||||
}
|
||||
|
||||
public function testConstructStatement(): void {
|
||||
|
|
|
@ -29,7 +29,7 @@ class BaseUpdate extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
if (!static::$interface) {
|
||||
$this->markTestSkipped(static::$implementation." database driver not available");
|
||||
}
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
// construct a fresh driver for each test
|
||||
$this->drv = new static::$dbDriverClass;
|
||||
|
@ -46,7 +46,7 @@ class BaseUpdate extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
// deconstruct the driver
|
||||
unset($this->drv);
|
||||
unset($this->path, $this->base, $this->vfs);
|
||||
self::clearData();
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public static function tearDownAfterClass(): void {
|
||||
|
@ -55,7 +55,7 @@ class BaseUpdate extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
static::dbRaze(static::$interface);
|
||||
}
|
||||
static::$interface = null;
|
||||
self::clearData();
|
||||
self::clearData(true);
|
||||
}
|
||||
|
||||
public function testLoadMissingFile(): void {
|
||||
|
|
|
@ -22,7 +22,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
if (!Driver::requirementsMet()) {
|
||||
$this->markTestSkipped("SQLite extension not loaded");
|
||||
}
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
// test files
|
||||
$this->files = [
|
||||
// cannot create files
|
||||
|
@ -108,10 +108,6 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::setConf();
|
||||
}
|
||||
|
||||
public function tearDown(): void {
|
||||
self::clearData();
|
||||
}
|
||||
|
||||
public function testFailToCreateDatabase(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Cmain/arsse.db";
|
||||
$this->assertException("fileUncreatable", "Db");
|
||||
|
|
|
@ -24,7 +24,7 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
if (!Driver::requirementsMet()) {
|
||||
$this->markTestSkipped("PDO-SQLite extension not loaded");
|
||||
}
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
// test files
|
||||
$this->files = [
|
||||
// cannot create files
|
||||
|
@ -110,10 +110,6 @@ class TestCreation extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::setConf();
|
||||
}
|
||||
|
||||
public function tearDown(): void {
|
||||
self::clearData();
|
||||
}
|
||||
|
||||
public function testFailToCreateDatabase(): void {
|
||||
Arsse::$conf->dbSQLite3File = $this->path."Cmain/arsse.db";
|
||||
$this->assertException("fileUncreatable", "Db");
|
||||
|
|
|
@ -15,47 +15,50 @@ class TestTransaction extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
protected $drv;
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
$drv = \Phake::mock(\JKingWeb\Arsse\Db\SQLite3\Driver::class);
|
||||
\Phake::when($drv)->savepointRelease->thenReturn(true);
|
||||
\Phake::when($drv)->savepointUndo->thenReturn(true);
|
||||
\Phake::when($drv)->savepointCreate->thenReturn(1)->thenReturn(2);
|
||||
parent::setUp();
|
||||
$drv = $this->mock(\JKingWeb\Arsse\Db\SQLite3\Driver::class);
|
||||
$drv->savepointRelease->returns(true);
|
||||
$drv->savepointUndo->returns(true);
|
||||
$drv->savepointCreate->returns(1, 2);
|
||||
$this->drv = $drv;
|
||||
}
|
||||
|
||||
public function testManipulateTransactions(): void {
|
||||
$tr1 = new Transaction($this->drv);
|
||||
$tr2 = new Transaction($this->drv);
|
||||
\Phake::verify($this->drv, \Phake::times(2))->savepointCreate;
|
||||
$drv = $this->drv->get();
|
||||
$tr1 = new Transaction($drv);
|
||||
$tr2 = new Transaction($drv);
|
||||
$this->drv->savepointCreate->twice()->called();
|
||||
$this->assertSame(1, $tr1->getIndex());
|
||||
$this->assertSame(2, $tr2->getIndex());
|
||||
unset($tr1);
|
||||
\Phake::verify($this->drv)->savepointUndo(1);
|
||||
$this->drv->savepointUndo->calledWith(1);
|
||||
unset($tr2);
|
||||
\Phake::verify($this->drv)->savepointUndo(2);
|
||||
$this->drv->savepointUndo->calledWith(2);
|
||||
}
|
||||
|
||||
public function testCloseTransactions(): void {
|
||||
$tr1 = new Transaction($this->drv);
|
||||
$tr2 = new Transaction($this->drv);
|
||||
$drv = $this->drv->get();
|
||||
$tr1 = new Transaction($drv);
|
||||
$tr2 = new Transaction($drv);
|
||||
$this->assertTrue($tr1->isPending());
|
||||
$this->assertTrue($tr2->isPending());
|
||||
$tr1->commit();
|
||||
$this->assertFalse($tr1->isPending());
|
||||
$this->assertTrue($tr2->isPending());
|
||||
\Phake::verify($this->drv)->savepointRelease(1);
|
||||
$this->drv->savepointRelease->calledWith(1);
|
||||
$tr2->rollback();
|
||||
$this->assertFalse($tr1->isPending());
|
||||
$this->assertFalse($tr2->isPending());
|
||||
\Phake::verify($this->drv)->savepointUndo(2);
|
||||
$this->drv->savepointUndo->calledWith(2);
|
||||
}
|
||||
|
||||
public function testIgnoreRollbackErrors(): void {
|
||||
\Phake::when($this->drv)->savepointUndo->thenThrow(new Exception("savepointStale"));
|
||||
$tr1 = new Transaction($this->drv);
|
||||
$tr2 = new Transaction($this->drv);
|
||||
$this->drv->savepointUndo->throws(new Exception("savepointStale"));
|
||||
$drv = $this->drv->get();
|
||||
$tr1 = new Transaction($drv);
|
||||
$tr2 = new Transaction($drv);
|
||||
unset($tr1, $tr2); // no exception should bubble up
|
||||
\Phake::verify($this->drv)->savepointUndo(1);
|
||||
\Phake::verify($this->drv)->savepointUndo(2);
|
||||
$this->drv->savepointUndo->calledWith(1);
|
||||
$this->drv->savepointUndo->calledWith(2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,16 +16,9 @@ class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function setUp(): void {
|
||||
self::clearData(false);
|
||||
// create a mock Lang object so as not to create a dependency loop
|
||||
Arsse::$lang = \Phake::mock(Lang::class);
|
||||
\Phake::when(Arsse::$lang)->msg->thenReturn("");
|
||||
}
|
||||
|
||||
public function tearDown(): void {
|
||||
// verify calls to the mock Lang object
|
||||
\Phake::verify(Arsse::$lang, \Phake::atLeast(0))->msg($this->isType("string"), $this->anything());
|
||||
\Phake::verifyNoOtherInteractions(Arsse::$lang);
|
||||
// clean up
|
||||
self::clearData(true);
|
||||
$this->langMock = $this->mock(Lang::class);
|
||||
$this->langMock->msg->returns("");
|
||||
Arsse::$lang = $this->langMock->get();
|
||||
}
|
||||
|
||||
public function testBaseClass(): void {
|
||||
|
|
|
@ -11,6 +11,7 @@ use JKingWeb\Arsse\Feed;
|
|||
use JKingWeb\Arsse\Database;
|
||||
use JKingWeb\Arsse\Misc\Date;
|
||||
use JKingWeb\Arsse\Test\Result;
|
||||
use Eloquent\Phony\Phpunit\Phony;
|
||||
|
||||
/**
|
||||
* @covers \JKingWeb\Arsse\Feed
|
||||
|
@ -92,12 +93,15 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->markTestSkipped("Test Web server is not accepting requests");
|
||||
}
|
||||
$this->base = self::$host."Feed/";
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
\Phake::when(Arsse::$db)->feedMatchLatest->thenReturn(new Result([]));
|
||||
\Phake::when(Arsse::$db)->feedMatchIds->thenReturn(new Result([]));
|
||||
\Phake::when(Arsse::$db)->feedRulesGet->thenReturn([]);
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
$this->dbMock->feedMatchLatest->with(Phony::wildcard())->returns(new Result([]));
|
||||
$this->dbMock->feedMatchLatest->with(1, Phony::any())->returns(new Result($this->latest));
|
||||
$this->dbMock->feedMatchIds->with(Phony::wildcard())->returns(new Result([]));
|
||||
$this->dbMock->feedMatchIds->with(1, Phony::wildcard())->returns(new Result($this->others));
|
||||
$this->dbMock->feedRulesGet->returns([]);
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
}
|
||||
|
||||
public function testParseAFeed(): void {
|
||||
|
@ -338,7 +342,10 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testMatchLatestArticles(): void {
|
||||
\Phake::when(Arsse::$db)->feedMatchLatest(1, $this->anything())->thenReturn(new Result($this->latest));
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
$this->dbMock->feedMatchLatest->with(Phony::wildcard())->returns(new Result([]));
|
||||
$this->dbMock->feedMatchLatest->with(1, Phony::any())->returns(new Result($this->latest));
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
$f = new Feed(1, $this->base."Matching/1");
|
||||
$this->assertCount(0, $f->newItems);
|
||||
$this->assertCount(0, $f->changedItems);
|
||||
|
@ -354,8 +361,6 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testMatchHistoricalArticles(): void {
|
||||
\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));
|
||||
$f = new Feed(1, $this->base."Matching/5");
|
||||
$this->assertCount(0, $f->newItems);
|
||||
$this->assertCount(0, $f->changedItems);
|
||||
|
@ -383,7 +388,11 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testApplyFilterRules(): void {
|
||||
\Phake::when(Arsse::$db)->feedMatchIds->thenReturn(new Result([
|
||||
$exp = [
|
||||
'jack' => ['new' => [false, true, true, false, true], 'changed' => [7 => true, 47 => true, 2112 => false, 1 => true, 42 => false]],
|
||||
'sam' => ['new' => [false, true, false, false, false], 'changed' => [7 => false, 47 => true, 2112 => false, 1 => false, 42 => false]],
|
||||
];
|
||||
$this->dbMock->feedMatchIds->returns(new Result([
|
||||
// these are the sixth through tenth entries in the feed; the title hashes have been omitted for brevity
|
||||
['id' => 7, 'guid' => '0f2a218c311e3d8105f1b075142a5d26dabf056ffc61abe77e96c8f071bbf4a7', 'edited' => null, 'url_title_hash' => "", 'url_content_hash' => '', 'title_content_hash' => ''],
|
||||
['id' => 47, 'guid' => '1c19e3b9018bc246b7414ae919ddebc88d0c575129e8c4a57b84b826c00f6db5', 'edited' => null, 'url_title_hash' => "", 'url_content_hash' => '', 'title_content_hash' => ''],
|
||||
|
@ -391,15 +400,12 @@ class TestFeed extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['id' => 1, 'guid' => '436070cda5713a0d9a8fdc8652c7ab142f0550697acfd5206a16c18aee355039', 'edited' => null, 'url_title_hash' => "", 'url_content_hash' => '', 'title_content_hash' => ''],
|
||||
['id' => 42, 'guid' => '1a731433a1904220ef26e731ada7262e1d5bcecae53e7b5df9e1f5713af6e5d3', 'edited' => null, 'url_title_hash' => "", 'url_content_hash' => '', 'title_content_hash' => ''],
|
||||
]));
|
||||
\Phake::when(Arsse::$db)->feedRulesGet->thenReturn([
|
||||
$this->dbMock->feedRulesGet->returns([
|
||||
'jack' => ['keep' => "", 'block' => '`A|W|J|S`u'],
|
||||
'sam' => ['keep' => "`B|T|X`u", 'block' => '`C`u'],
|
||||
]);
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
$f = new Feed(5, $this->base."Filtering/1");
|
||||
$exp = [
|
||||
'jack' => ['new' => [false, true, true, false, true], 'changed' => [7 => true, 47 => true, 2112 => false, 1 => true, 42 => false]],
|
||||
'sam' => ['new' => [false, true, false, false, false], 'changed' => [7 => false, 47 => true, 2112 => false, 1 => false, 42 => false]],
|
||||
];
|
||||
$this->assertSame($exp, $f->filteredItems);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ class TestFetching extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->markTestSkipped("Test Web server is not accepting requests");
|
||||
}
|
||||
$this->base = self::$host."Feed/";
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
}
|
||||
|
||||
|
|
|
@ -17,11 +17,11 @@ class TestFile extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
protected $proc;
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
// create a mock Import/Export processor with stubbed underlying import/export routines
|
||||
$this->proc = \Phake::partialMock(AbstractImportExport::class);
|
||||
\Phake::when($this->proc)->export->thenReturn("EXPORT_FILE");
|
||||
\Phake::when($this->proc)->import->thenReturn(true);
|
||||
$this->proc = $this->partialMock(AbstractImportExport::class);
|
||||
$this->proc->export->returns("EXPORT_FILE");
|
||||
$this->proc->import->returns(true);
|
||||
$this->vfs = vfsStream::setup("root", null, [
|
||||
'exportGoodFile' => "",
|
||||
'exportGoodDir' => [],
|
||||
|
@ -41,7 +41,7 @@ class TestFile extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->path = null;
|
||||
$this->vfs = null;
|
||||
$this->proc = null;
|
||||
self::clearData();
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
/** @dataProvider provideFileExports */
|
||||
|
@ -50,13 +50,13 @@ class TestFile extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
try {
|
||||
if ($exp instanceof \JKingWeb\Arsse\AbstractException) {
|
||||
$this->assertException($exp);
|
||||
$this->proc->exportFile($path, $user, $flat);
|
||||
$this->proc->get()->exportFile($path, $user, $flat);
|
||||
} else {
|
||||
$this->assertSame($exp, $this->proc->exportFile($path, $user, $flat));
|
||||
$this->assertSame($exp, $this->proc->get()->exportFile($path, $user, $flat));
|
||||
$this->assertSame("EXPORT_FILE", $this->vfs->getChild($file)->getContent());
|
||||
}
|
||||
} finally {
|
||||
\Phake::verify($this->proc)->export($user, $flat);
|
||||
$this->proc->export->calledWith($user, $flat);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,12 +89,12 @@ class TestFile extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
try {
|
||||
if ($exp instanceof \JKingWeb\Arsse\AbstractException) {
|
||||
$this->assertException($exp);
|
||||
$this->proc->importFile($path, $user, $flat, $replace);
|
||||
$this->proc->get()->importFile($path, $user, $flat, $replace);
|
||||
} else {
|
||||
$this->assertSame($exp, $this->proc->importFile($path, $user, $flat, $replace));
|
||||
$this->assertSame($exp, $this->proc->get()->importFile($path, $user, $flat, $replace));
|
||||
}
|
||||
} finally {
|
||||
\Phake::verify($this->proc, \Phake::times((int) ($exp === true)))->import($user, "GOOD_FILE", $flat, $replace);
|
||||
$this->proc->import->times((int) ($exp === true))->calledWith($user, "GOOD_FILE", $flat, $replace);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,11 +24,11 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
];
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
// create a mock user manager
|
||||
Arsse::$user = \Phake::mock(\JKingWeb\Arsse\User::class);
|
||||
Arsse::$user = $this->mock(\JKingWeb\Arsse\User::class)->get();
|
||||
// create a mock Import/Export processor
|
||||
$this->proc = \Phake::partialMock(AbstractImportExport::class);
|
||||
$this->proc = $this->partialMock(AbstractImportExport::class);
|
||||
// initialize an SQLite memeory database
|
||||
static::setConf();
|
||||
try {
|
||||
|
@ -142,12 +142,12 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function tearDown(): void {
|
||||
$this->drv = null;
|
||||
$this->proc = null;
|
||||
self::clearData();
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
public function testImportForAMissingUser(): void {
|
||||
$this->assertException("doesNotExist", "User", "ExceptionConflict");
|
||||
$this->proc->import("no.one@example.com", "", false, false);
|
||||
$this->proc->get()->import("no.one@example.com", "", false, false);
|
||||
}
|
||||
|
||||
public function testImportWithInvalidFolder(): void {
|
||||
|
@ -155,9 +155,9 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
], [1 =>
|
||||
['id' => 1, 'name' => "", 'parent' => 0],
|
||||
]];
|
||||
\Phake::when($this->proc)->parse->thenReturn($in);
|
||||
$this->proc->parse->returns($in);
|
||||
$this->assertException("invalidFolderName", "ImportExport");
|
||||
$this->proc->import("john.doe@example.com", "", false, false);
|
||||
$this->proc->get()->import("john.doe@example.com", "", false, false);
|
||||
}
|
||||
|
||||
public function testImportWithDuplicateFolder(): void {
|
||||
|
@ -166,9 +166,9 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['id' => 1, 'name' => "New", 'parent' => 0],
|
||||
['id' => 2, 'name' => "New", 'parent' => 0],
|
||||
]];
|
||||
\Phake::when($this->proc)->parse->thenReturn($in);
|
||||
$this->proc->parse->returns($in);
|
||||
$this->assertException("invalidFolderCopy", "ImportExport");
|
||||
$this->proc->import("john.doe@example.com", "", false, false);
|
||||
$this->proc->get()->import("john.doe@example.com", "", false, false);
|
||||
}
|
||||
|
||||
public function testMakeNoEffectiveChanges(): void {
|
||||
|
@ -187,11 +187,11 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['id' => 5, 'name' => "Local", 'parent' => 4],
|
||||
['id' => 6, 'name' => "National", 'parent' => 4],
|
||||
]];
|
||||
\Phake::when($this->proc)->parse->thenReturn($in);
|
||||
$this->proc->parse->returns($in);
|
||||
$exp = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$this->proc->import("john.doe@example.com", "", false, false);
|
||||
$this->proc->get()->import("john.doe@example.com", "", false, false);
|
||||
$this->compareExpectations($this->drv, $exp);
|
||||
$this->proc->import("john.doe@example.com", "", false, true);
|
||||
$this->proc->get()->import("john.doe@example.com", "", false, true);
|
||||
$this->compareExpectations($this->drv, $exp);
|
||||
}
|
||||
|
||||
|
@ -212,8 +212,8 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['id' => 6, 'name' => "National", 'parent' => 4],
|
||||
['id' => 7, 'name' => "Nature", 'parent' => 0], // new folder
|
||||
]];
|
||||
\Phake::when($this->proc)->parse->thenReturn($in);
|
||||
$this->proc->import("john.doe@example.com", "", false, true);
|
||||
$this->proc->parse->returns($in);
|
||||
$this->proc->get()->import("john.doe@example.com", "", false, true);
|
||||
$exp = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$exp['arsse_subscriptions']['rows'][3] = [4, "john.doe@example.com", null, 4, "CBC"];
|
||||
$exp['arsse_folders']['rows'][] = [7, "john.doe@example.com", null, "Nature"];
|
||||
|
@ -224,8 +224,8 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$in = [[
|
||||
['url' => "http://localhost:8000/Import/some-feed", 'title' => "Some Feed", 'folder' => 0, 'tags' => ["frequent", "cryptic"]], //one existing tag and one new one
|
||||
], []];
|
||||
\Phake::when($this->proc)->parse->thenReturn($in);
|
||||
$this->proc->import("john.doe@example.com", "", false, false);
|
||||
$this->proc->parse->returns($in);
|
||||
$this->proc->get()->import("john.doe@example.com", "", false, false);
|
||||
$exp = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$exp['arsse_feeds']['rows'][] = [7, "http://localhost:8000/Import/some-feed", "Some feed"]; // author-supplied and user-supplied titles differ
|
||||
$exp['arsse_subscriptions']['rows'][] = [7, "john.doe@example.com", null, 7, "Some Feed"];
|
||||
|
@ -239,9 +239,9 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$in = [[
|
||||
['url' => "http://localhost:8000/Import/some-feed", 'title' => "Some Feed", 'folder' => 0, 'tags' => [""]],
|
||||
], []];
|
||||
\Phake::when($this->proc)->parse->thenReturn($in);
|
||||
$this->proc->parse->returns($in);
|
||||
$this->assertException("invalidTagName", "ImportExport");
|
||||
$this->proc->import("john.doe@example.com", "", false, false);
|
||||
$this->proc->get()->import("john.doe@example.com", "", false, false);
|
||||
}
|
||||
|
||||
public function testReplaceData(): void {
|
||||
|
@ -250,8 +250,8 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
], [1 =>
|
||||
['id' => 1, 'name' => "Photography", 'parent' => 0],
|
||||
]];
|
||||
\Phake::when($this->proc)->parse->thenReturn($in);
|
||||
$this->proc->import("john.doe@example.com", "", false, true);
|
||||
$this->proc->parse->returns($in);
|
||||
$this->proc->get()->import("john.doe@example.com", "", false, true);
|
||||
$exp = $this->primeExpectations($this->data, $this->checkTables);
|
||||
$exp['arsse_feeds']['rows'][] = [7, "http://localhost:8000/Import/some-feed", "Some feed"]; // author-supplied and user-supplied titles differ
|
||||
$exp['arsse_subscriptions']['rows'] = [[7, "john.doe@example.com", 4, 7, "Some Feed"]];
|
||||
|
|
|
@ -7,9 +7,11 @@ declare(strict_types=1);
|
|||
namespace JKingWeb\Arsse\TestCase\ImportExport;
|
||||
|
||||
use JKingWeb\Arsse\Arsse;
|
||||
use JKingWeb\Arsse\Database;
|
||||
use JKingWeb\Arsse\Test\Result;
|
||||
use JKingWeb\Arsse\ImportExport\OPML;
|
||||
use JKingWeb\Arsse\ImportExport\Exception;
|
||||
use ReflectionMethod;
|
||||
|
||||
/** @covers \JKingWeb\Arsse\ImportExport\OPML<extended> */
|
||||
class TestOPML extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
|
@ -80,27 +82,25 @@ OPML_EXPORT_SERIALIZATION;
|
|||
OPML_EXPORT_SERIALIZATION;
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
Arsse::$db = \Phake::mock(\JKingWeb\Arsse\Database::class);
|
||||
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
|
||||
parent::setUp();
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
$this->dbMock->userExists->returns(true);
|
||||
$this->dbMock->folderList->with("john.doe@example.com")->returns(new Result($this->folders));
|
||||
$this->dbMock->subscriptionList->with("john.doe@example.com")->returns(new Result($this->subscriptions));
|
||||
$this->dbMock->tagSummarize->with("john.doe@example.com")->returns(new Result($this->tags));
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
}
|
||||
|
||||
public function testExportToOpml(): void {
|
||||
\Phake::when(Arsse::$db)->folderList("john.doe@example.com")->thenReturn(new Result($this->folders));
|
||||
\Phake::when(Arsse::$db)->subscriptionList("john.doe@example.com")->thenReturn(new Result($this->subscriptions));
|
||||
\Phake::when(Arsse::$db)->tagSummarize("john.doe@example.com")->thenReturn(new Result($this->tags));
|
||||
$this->assertXmlStringEqualsXmlString($this->serialization, (new OPML)->export("john.doe@example.com"));
|
||||
}
|
||||
|
||||
public function testExportToFlatOpml(): void {
|
||||
\Phake::when(Arsse::$db)->folderList("john.doe@example.com")->thenReturn(new Result($this->folders));
|
||||
\Phake::when(Arsse::$db)->subscriptionList("john.doe@example.com")->thenReturn(new Result($this->subscriptions));
|
||||
\Phake::when(Arsse::$db)->tagSummarize("john.doe@example.com")->thenReturn(new Result($this->tags));
|
||||
$this->assertXmlStringEqualsXmlString($this->serializationFlat, (new OPML)->export("john.doe@example.com", true));
|
||||
}
|
||||
|
||||
public function testExportToOpmlAMissingUser(): void {
|
||||
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
|
||||
$this->dbMock->userExists->returns(false);
|
||||
$this->assertException("doesNotExist", "User", "ExceptionConflict");
|
||||
(new OPML)->export("john.doe@example.com");
|
||||
}
|
||||
|
@ -108,13 +108,15 @@ OPML_EXPORT_SERIALIZATION;
|
|||
/** @dataProvider provideParserData */
|
||||
public function testParseOpmlForImport(string $file, bool $flat, $exp): void {
|
||||
$data = file_get_contents(\JKingWeb\Arsse\DOCROOT."Import/OPML/$file");
|
||||
// set up a partial mock to make the ImportExport::parse() method visible
|
||||
$parser = \Phake::makeVisible(\Phake::partialMock(OPML::class));
|
||||
if ($exp instanceof \JKingWeb\Arsse\AbstractException) {
|
||||
// make the ImportExport::parse() method visible
|
||||
$parser = new OPML;
|
||||
$parseFunc = new \ReflectionMethod($parser, "parse");
|
||||
$parseFunc->setAccessible(true);
|
||||
if ($exp instanceof \Exception) {
|
||||
$this->assertException($exp);
|
||||
$parser->parse($data, $flat);
|
||||
$parseFunc->invoke($parser, $data, $flat);
|
||||
} else {
|
||||
$this->assertSame($exp, $parser->parse($data, $flat));
|
||||
$this->assertSame($exp, $parseFunc->invoke($parser, $data, $flat));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,10 +10,6 @@ use JKingWeb\Arsse\Misc\Date;
|
|||
|
||||
/** @covers \JKingWeb\Arsse\Misc\Date */
|
||||
class TestDate extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
}
|
||||
|
||||
public function testNormalizeADate(): void {
|
||||
$exp = new \DateTimeImmutable("2018-01-01T00:00:00Z");
|
||||
$this->assertEquals($exp, Date::normalize(1514764800));
|
||||
|
|
|
@ -10,9 +10,6 @@ use JKingWeb\Arsse\Misc\URL;
|
|||
|
||||
/** @covers \JKingWeb\Arsse\Misc\URL */
|
||||
class TestURL extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
}
|
||||
|
||||
/** @dataProvider provideNormalizations */
|
||||
public function testNormalizeAUrl(string $url, string $exp, string $user = null, string $pass = null): void {
|
||||
|
|
|
@ -12,9 +12,6 @@ use JKingWeb\Arsse\Test\Result;
|
|||
|
||||
/** @covers \JKingWeb\Arsse\Misc\ValueInfo */
|
||||
class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
}
|
||||
|
||||
public function testGetIntegerInfo(): void {
|
||||
$tests = [
|
||||
|
|
|
@ -24,7 +24,8 @@ use Laminas\Diactoros\Response\EmptyResponse;
|
|||
class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
/** @var \JKingWeb\Arsse\REST\Fever\API */
|
||||
protected $h;
|
||||
|
||||
protected $hMock;
|
||||
protected $userId = "john.doe@example.com";
|
||||
protected $articles = [
|
||||
'db' => [
|
||||
[
|
||||
|
@ -141,35 +142,35 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
],
|
||||
],
|
||||
];
|
||||
|
||||
protected function v($value) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
protected function req($dataGet, $dataPost = "", string $method = "POST", string $type = null, string $target = "", string $user = null): ServerRequest {
|
||||
protected function req($dataGet, $dataPost = "", string $method = "POST", ?string $type = null, string $target = "", ?string $user = null): ResponseInterface {
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
$this->h = $this->hMock->get();
|
||||
$prefix = "/fever/";
|
||||
$url = $prefix.$target;
|
||||
$type = $type ?? "application/x-www-form-urlencoded";
|
||||
return $this->serverRequest($method, $url, $prefix, [], [], $dataPost, $type, $dataGet, $user);
|
||||
return $this->h->dispatch($this->serverRequest($method, $url, $prefix, [], [], $dataPost, $type, $dataGet, $user));
|
||||
}
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
self::setConf();
|
||||
// create a mock user manager
|
||||
Arsse::$user = \Phake::mock(User::class);
|
||||
\Phake::when(Arsse::$user)->auth->thenReturn(true);
|
||||
Arsse::$user->id = "john.doe@example.com";
|
||||
$this->userMock = $this->mock(User::class);
|
||||
$this->userMock->auth->returns(true);
|
||||
Arsse::$user = $this->userMock->get();
|
||||
Arsse::$user->id = $this->userId;
|
||||
// create a mock database interface
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
\Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(Transaction::class));
|
||||
\Phake::when(Arsse::$db)->tokenLookup->thenReturn(['user' => "john.doe@example.com"]);
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
$this->dbMock->begin->returns($this->mock(Transaction::class));
|
||||
$this->dbMock->tokenLookup->returns(['user' => "john.doe@example.com"]);
|
||||
// instantiate the handler as a partial mock to simplify testing
|
||||
$this->h = \Phake::partialMock(API::class);
|
||||
\Phake::when($this->h)->baseResponse->thenReturn([]);
|
||||
}
|
||||
|
||||
public function tearDown(): void {
|
||||
self::clearData();
|
||||
$this->hMock = $this->partialMock(API::class);
|
||||
$this->hMock->baseResponse->returns([]);
|
||||
}
|
||||
|
||||
/** @dataProvider provideTokenAuthenticationRequests */
|
||||
|
@ -179,17 +180,16 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
'userSessionEnforced' => $tokenEnforced,
|
||||
], true);
|
||||
Arsse::$user->id = null;
|
||||
\Phake::when(Arsse::$db)->tokenLookup->thenThrow(new ExceptionInput("subjectMissing"));
|
||||
\Phake::when(Arsse::$db)->tokenLookup("fever.login", "validtoken")->thenReturn(['user' => "jane.doe@example.com"]);
|
||||
$this->dbMock->tokenLookup->throws(new ExceptionInput("subjectMissing"));
|
||||
$this->dbMock->tokenLookup->with("fever.login", "validtoken")->returns(['user' => "jane.doe@example.com"]);
|
||||
// test only the authentication process
|
||||
\Phake::when($this->h)->baseResponse->thenReturnCallback(function(bool $authenticated) {
|
||||
$this->hMock->baseResponse->does(function(bool $authenticated) {
|
||||
return ['auth' => (int) $authenticated];
|
||||
});
|
||||
\Phake::when($this->h)->processRequest->thenReturnCallback(function($out, $G, $P) {
|
||||
$this->hMock->processRequest->does(function($out, $G, $P) {
|
||||
return $out;
|
||||
});
|
||||
$act = $this->h->dispatch($this->req($dataGet, $dataPost, "POST", null, "", $httpUser));
|
||||
$this->assertMessage($exp, $act);
|
||||
$this->assertMessage($exp, $this->req($dataGet, $dataPost, "POST", null, "", $httpUser));
|
||||
}
|
||||
|
||||
public function provideTokenAuthenticationRequests(): iterable {
|
||||
|
@ -245,12 +245,12 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testListGroups(): void {
|
||||
\Phake::when(Arsse::$db)->tagList(Arsse::$user->id)->thenReturn(new Result([
|
||||
$this->dbMock->tagList->with($this->userId)->returns(new Result([
|
||||
['id' => 1, 'name' => "Fascinating", 'subscriptions' => 2],
|
||||
['id' => 2, 'name' => "Interesting", 'subscriptions' => 2],
|
||||
['id' => 3, 'name' => "Boring", 'subscriptions' => 0],
|
||||
]));
|
||||
\Phake::when(Arsse::$db)->tagSummarize(Arsse::$user->id)->thenReturn(new Result([
|
||||
$this->dbMock->tagSummarize->with($this->userId)->returns(new Result([
|
||||
['id' => 1, 'name' => "Fascinating", 'subscription' => 1],
|
||||
['id' => 1, 'name' => "Fascinating", 'subscription' => 2],
|
||||
['id' => 2, 'name' => "Interesting", 'subscription' => 1],
|
||||
|
@ -267,17 +267,16 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['group_id' => 2, 'feed_ids' => "1,3"],
|
||||
],
|
||||
]);
|
||||
$act = $this->h->dispatch($this->req("api&groups"));
|
||||
$this->assertMessage($exp, $act);
|
||||
$this->assertMessage($exp, $this->req("api&groups"));
|
||||
}
|
||||
|
||||
public function testListFeeds(): void {
|
||||
\Phake::when(Arsse::$db)->subscriptionList(Arsse::$user->id)->thenReturn(new Result([
|
||||
$this->dbMock->subscriptionList->with($this->userId)->returns(new Result([
|
||||
['id' => 1, 'feed' => 5, 'title' => "Ankh-Morpork News", 'url' => "http://example.com/feed", 'source' => "http://example.com/", 'edited' => "2019-01-01 21:12:00", 'icon_url' => "http://example.com/favicon.ico", 'icon_id' => 42],
|
||||
['id' => 2, 'feed' => 9, 'title' => "Ook, Ook Eek Ook!", 'url' => "http://example.net/feed", 'source' => "http://example.net/", 'edited' => "1988-06-24 12:21:00", 'icon_url' => "", 'icon_id' => null],
|
||||
['id' => 3, 'feed' => 1, 'title' => "The Last Soul", 'url' => "http://example.org/feed", 'source' => "http://example.org/", 'edited' => "1991-08-12 03:22:00", 'icon_url' => "http://example.org/favicon.ico", 'icon_id' => 42],
|
||||
]));
|
||||
\Phake::when(Arsse::$db)->tagSummarize(Arsse::$user->id)->thenReturn(new Result([
|
||||
$this->dbMock->tagSummarize->with($this->userId)->returns(new Result([
|
||||
['id' => 1, 'name' => "Fascinating", 'subscription' => 1],
|
||||
['id' => 1, 'name' => "Fascinating", 'subscription' => 2],
|
||||
['id' => 2, 'name' => "Interesting", 'subscription' => 1],
|
||||
|
@ -294,23 +293,21 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
['group_id' => 2, 'feed_ids' => "1,3"],
|
||||
],
|
||||
]);
|
||||
$act = $this->h->dispatch($this->req("api&feeds"));
|
||||
$this->assertMessage($exp, $act);
|
||||
$this->assertMessage($exp, $this->req("api&feeds"));
|
||||
}
|
||||
|
||||
/** @dataProvider provideItemListContexts */
|
||||
public function testListItems(string $url, Context $c, bool $desc): void {
|
||||
$fields = ["id", "subscription", "title", "author", "content", "url", "starred", "unread", "published_date"];
|
||||
$order = [$desc ? "id desc" : "id"];
|
||||
\Phake::when(Arsse::$db)->articleList->thenReturn(new Result($this->articles['db']));
|
||||
\Phake::when(Arsse::$db)->articleCount(Arsse::$user->id, (new Context)->hidden(false))->thenReturn(1024);
|
||||
$this->dbMock->articleList->returns(new Result($this->articles['db']));
|
||||
$this->dbMock->articleCount->with($this->userId, (new Context)->hidden(false))->returns(1024);
|
||||
$exp = new JsonResponse([
|
||||
'items' => $this->articles['rest'],
|
||||
'total_items' => 1024,
|
||||
]);
|
||||
$act = $this->h->dispatch($this->req("api&$url"));
|
||||
$this->assertMessage($exp, $act);
|
||||
\Phake::verify(Arsse::$db)->articleList(Arsse::$user->id, $c, $fields, $order);
|
||||
$this->assertMessage($exp, $this->req("api&$url"));
|
||||
$this->dbMock->articleList->calledWith($this->userId, $this->equalTo($c), $fields, $order);
|
||||
}
|
||||
|
||||
public function provideItemListContexts(): iterable {
|
||||
|
@ -332,35 +329,34 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function testListItemIds(): void {
|
||||
$saved = [['id' => 1],['id' => 2],['id' => 3]];
|
||||
$unread = [['id' => 4],['id' => 5],['id' => 6]];
|
||||
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true)->hidden(false))->thenReturn(new Result($saved));
|
||||
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->unread(true)->hidden(false))->thenReturn(new Result($unread));
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->starred(true)->hidden(false))->returns(new Result($saved));
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->unread(true)->hidden(false))->returns(new Result($unread));
|
||||
$exp = new JsonResponse(['saved_item_ids' => "1,2,3"]);
|
||||
$this->assertMessage($exp, $this->h->dispatch($this->req("api&saved_item_ids")));
|
||||
$this->assertMessage($exp, $this->req("api&saved_item_ids"));
|
||||
$exp = new JsonResponse(['unread_item_ids' => "4,5,6"]);
|
||||
$this->assertMessage($exp, $this->h->dispatch($this->req("api&unread_item_ids")));
|
||||
$this->assertMessage($exp, $this->req("api&unread_item_ids"));
|
||||
}
|
||||
|
||||
public function testListHotLinks(): void {
|
||||
// hot links are not actually implemented, so an empty array should be all we get
|
||||
$exp = new JsonResponse(['links' => []]);
|
||||
$this->assertMessage($exp, $this->h->dispatch($this->req("api&links")));
|
||||
$this->assertMessage($exp, $this->req("api&links"));
|
||||
}
|
||||
|
||||
/** @dataProvider provideMarkingContexts */
|
||||
public function testSetMarks(string $post, Context $c, array $data, array $out): void {
|
||||
$saved = [['id' => 1],['id' => 2],['id' => 3]];
|
||||
$unread = [['id' => 4],['id' => 5],['id' => 6]];
|
||||
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true)->hidden(false))->thenReturn(new Result($saved));
|
||||
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->unread(true)->hidden(false))->thenReturn(new Result($unread));
|
||||
\Phake::when(Arsse::$db)->articleMark->thenReturn(0);
|
||||
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), (new Context)->article(2112))->thenThrow(new \JKingWeb\Arsse\Db\ExceptionInput("subjectMissing"));
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->starred(true)->hidden(false))->returns(new Result($saved));
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->unread(true)->hidden(false))->returns(new Result($unread));
|
||||
$this->dbMock->articleMark->returns(0);
|
||||
$this->dbMock->articleMark->with($this->userId, $this->anything(), (new Context)->article(2112))->throws(new \JKingWeb\Arsse\Db\ExceptionInput("subjectMissing"));
|
||||
$exp = new JsonResponse($out);
|
||||
$act = $this->h->dispatch($this->req("api", $post));
|
||||
$this->assertMessage($exp, $act);
|
||||
$this->assertMessage($exp, $this->req("api", $post));
|
||||
if ($c && $data) {
|
||||
\Phake::verify(Arsse::$db)->articleMark(Arsse::$user->id, $data, $c);
|
||||
$this->dbMock->articleMark->calledWith($this->userId, $data, $this->equalTo($c));
|
||||
} else {
|
||||
\Phake::verify(Arsse::$db, \Phake::times(0))->articleMark;
|
||||
$this->dbMock->articleMark->never()->called();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,17 +364,16 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function testSetMarksWithQuery(string $get, Context $c, array $data, array $out): void {
|
||||
$saved = [['id' => 1],['id' => 2],['id' => 3]];
|
||||
$unread = [['id' => 4],['id' => 5],['id' => 6]];
|
||||
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->starred(true)->hidden(false))->thenReturn(new Result($saved));
|
||||
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->unread(true)->hidden(false))->thenReturn(new Result($unread));
|
||||
\Phake::when(Arsse::$db)->articleMark->thenReturn(0);
|
||||
\Phake::when(Arsse::$db)->articleMark(Arsse::$user->id, $this->anything(), (new Context)->article(2112))->thenThrow(new \JKingWeb\Arsse\Db\ExceptionInput("subjectMissing"));
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->starred(true)->hidden(false))->returns(new Result($saved));
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->unread(true)->hidden(false))->returns(new Result($unread));
|
||||
$this->dbMock->articleMark->returns(0);
|
||||
$this->dbMock->articleMark->with($this->userId, $this->anything(), (new Context)->article(2112))->throws(new \JKingWeb\Arsse\Db\ExceptionInput("subjectMissing"));
|
||||
$exp = new JsonResponse($out);
|
||||
$act = $this->h->dispatch($this->req("api&$get"));
|
||||
$this->assertMessage($exp, $act);
|
||||
$this->assertMessage($exp, $this->req("api&$get"));
|
||||
if ($c && $data) {
|
||||
\Phake::verify(Arsse::$db)->articleMark(Arsse::$user->id, $data, $c);
|
||||
$this->dbMock->articleMark->calledWith($this->userId, $data, $this->equalTo($c));
|
||||
} else {
|
||||
\Phake::verify(Arsse::$db, \Phake::times(0))->articleMark;
|
||||
$this->dbMock->articleMark->never()->called();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -421,97 +416,89 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
/** @dataProvider provideInvalidRequests */
|
||||
public function testSendInvalidRequests(ServerRequest $req, ResponseInterface $exp): void {
|
||||
$this->assertMessage($exp, $this->h->dispatch($req));
|
||||
public function testSendInvalidRequests(string $get, string $post, string $method, ?string $type, ResponseInterface $exp): void {
|
||||
$this->assertMessage($exp, $this->req($get, $post, $method, $type));
|
||||
}
|
||||
|
||||
public function provideInvalidRequests(): iterable {
|
||||
return [
|
||||
'Not an API request' => [$this->req(""), new EmptyResponse(404)],
|
||||
'Wrong method' => [$this->req("api", "", "PUT"), new EmptyResponse(405, ['Allow' => "OPTIONS,POST"])],
|
||||
'Non-standard method' => [$this->req("api", "", "GET"), new JsonResponse([])],
|
||||
'Wrong content type' => [$this->req("api", '{"api_key":"validToken"}', "POST", "application/json"), new EmptyResponse(415, ['Accept' => "application/x-www-form-urlencoded, multipart/form-data"])],
|
||||
'Non-standard content type' => [$this->req("api", '{"api_key":"validToken"}', "POST", "multipart/form-data; boundary=33b68964f0de4c1f-5144aa6caaa6e4a8-18bfaf416a1786c8-5c5053a45f221bc1"), new JsonResponse([])],
|
||||
'Not an API request' => ["", "", "POST", null, new EmptyResponse(404)],
|
||||
'Wrong method' => ["api", "", "PUT", null, new EmptyResponse(405, ['Allow' => "OPTIONS,POST"])],
|
||||
'Non-standard method' => ["api", "", "GET", null, new JsonResponse([])],
|
||||
'Wrong content type' => ["api", '{"api_key":"validToken"}', "POST", "application/json", new EmptyResponse(415, ['Accept' => "application/x-www-form-urlencoded, multipart/form-data"])],
|
||||
'Non-standard content type' => ["api", '{"api_key":"validToken"}', "POST", "multipart/form-data; boundary=33b68964f0de4c1f-5144aa6caaa6e4a8-18bfaf416a1786c8-5c5053a45f221bc1", new JsonResponse([])],
|
||||
];
|
||||
}
|
||||
|
||||
public function testMakeABaseQuery(): void {
|
||||
$this->h = \Phake::partialMock(API::class);
|
||||
\Phake::when($this->h)->logIn->thenReturn(true);
|
||||
\Phake::when(Arsse::$db)->subscriptionRefreshed(Arsse::$user->id)->thenReturn(new \DateTimeImmutable("2000-01-01T00:00:00Z"));
|
||||
$this->hMock->baseResponse->forwards();
|
||||
$this->hMock->logIn->returns(true);
|
||||
$this->dbMock->subscriptionRefreshed->with($this->userId)->returns(new \DateTimeImmutable("2000-01-01T00:00:00Z"));
|
||||
$exp = new JsonResponse([
|
||||
'api_version' => API::LEVEL,
|
||||
'auth' => 1,
|
||||
'last_refreshed_on_time' => 946684800,
|
||||
]);
|
||||
$act = $this->h->dispatch($this->req("api"));
|
||||
$this->assertMessage($exp, $act);
|
||||
\Phake::when(Arsse::$db)->subscriptionRefreshed(Arsse::$user->id)->thenReturn(null); // no subscriptions
|
||||
$this->assertMessage($exp, $this->req("api"));
|
||||
$this->dbMock->subscriptionRefreshed->with($this->userId)->returns(null); // no subscriptions
|
||||
$exp = new JsonResponse([
|
||||
'api_version' => API::LEVEL,
|
||||
'auth' => 1,
|
||||
'last_refreshed_on_time' => null,
|
||||
]);
|
||||
$act = $this->h->dispatch($this->req("api"));
|
||||
$this->assertMessage($exp, $act);
|
||||
\Phake::when($this->h)->logIn->thenReturn(false);
|
||||
$this->assertMessage($exp, $this->req("api"));
|
||||
$this->hMock->logIn->returns(false);
|
||||
$exp = new JsonResponse([
|
||||
'api_version' => API::LEVEL,
|
||||
'auth' => 0,
|
||||
]);
|
||||
$act = $this->h->dispatch($this->req("api"));
|
||||
$this->assertMessage($exp, $act);
|
||||
$this->assertMessage($exp, $this->req("api"));
|
||||
}
|
||||
|
||||
public function testUndoReadMarks(): void {
|
||||
$unread = [['id' => 4],['id' => 5],['id' => 6]];
|
||||
$out = ['unread_item_ids' => "4,5,6"];
|
||||
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(1)->hidden(false), ["marked_date"], ["marked_date desc"])->thenReturn(new Result([['marked_date' => "2000-01-01 00:00:00"]]));
|
||||
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->unread(true)->hidden(false))->thenReturn(new Result($unread));
|
||||
\Phake::when(Arsse::$db)->articleMark->thenReturn(0);
|
||||
$this->dbMock->articleList->with($this->userId, $this->equalTo((new Context)->limit(1)->hidden(false)), ["marked_date"], ["marked_date desc"])->returns(new Result([['marked_date' => "2000-01-01 00:00:00"]]));
|
||||
$this->dbMock->articleList->with($this->userId, $this->equalTo((new Context)->unread(true)->hidden(false)))->returns(new Result($unread));
|
||||
$this->dbMock->articleMark->returns(0);
|
||||
$exp = new JsonResponse($out);
|
||||
$act = $this->h->dispatch($this->req("api", ['unread_recently_read' => 1]));
|
||||
$this->assertMessage($exp, $act);
|
||||
\Phake::verify(Arsse::$db)->articleMark(Arsse::$user->id, ['read' => false], (new Context)->unread(false)->markedSince("1999-12-31T23:59:45Z")->hidden(false));
|
||||
\Phake::when(Arsse::$db)->articleList(Arsse::$user->id, (new Context)->limit(1)->hidden(false), ["marked_date"], ["marked_date desc"])->thenReturn(new Result([]));
|
||||
$act = $this->h->dispatch($this->req("api", ['unread_recently_read' => 1]));
|
||||
$this->assertMessage($exp, $act);
|
||||
\Phake::verify(Arsse::$db)->articleMark; // only called one time, above
|
||||
$this->assertMessage($exp, $this->req("api", ['unread_recently_read' => 1]));
|
||||
$this->dbMock->articleMark->calledWith($this->userId, ['read' => false], $this->equalTo((new Context)->unread(false)->markedSince("1999-12-31T23:59:45Z")->hidden(false)));
|
||||
$this->dbMock->articleList->with($this->userId, (new Context)->limit(1)->hidden(false), ["marked_date"], ["marked_date desc"])->returns(new Result([]));
|
||||
$this->assertMessage($exp, $this->req("api", ['unread_recently_read' => 1]));
|
||||
$this->dbMock->articleMark->once()->called(); // only called one time, above
|
||||
}
|
||||
|
||||
public function testOutputToXml(): void {
|
||||
\Phake::when($this->h)->processRequest->thenReturn([
|
||||
$this->hMock->processRequest->returns([
|
||||
'items' => $this->articles['rest'],
|
||||
'total_items' => 1024,
|
||||
]);
|
||||
$exp = new XmlResponse("<response><items><item><id>101</id><feed_id>8</feed_id><title>Article title 1</title><author></author><html><p>Article content 1</p></html><url>http://example.com/1</url><is_saved>0</is_saved><is_read>0</is_read><created_on_time>946684800</created_on_time></item><item><id>102</id><feed_id>8</feed_id><title>Article title 2</title><author></author><html><p>Article content 2</p></html><url>http://example.com/2</url><is_saved>0</is_saved><is_read>1</is_read><created_on_time>946771200</created_on_time></item><item><id>103</id><feed_id>9</feed_id><title>Article title 3</title><author></author><html><p>Article content 3</p></html><url>http://example.com/3</url><is_saved>1</is_saved><is_read>0</is_read><created_on_time>946857600</created_on_time></item><item><id>104</id><feed_id>9</feed_id><title>Article title 4</title><author></author><html><p>Article content 4</p></html><url>http://example.com/4</url><is_saved>1</is_saved><is_read>1</is_read><created_on_time>946944000</created_on_time></item><item><id>105</id><feed_id>10</feed_id><title>Article title 5</title><author></author><html><p>Article content 5</p></html><url>http://example.com/5</url><is_saved>0</is_saved><is_read>0</is_read><created_on_time>947030400</created_on_time></item></items><total_items>1024</total_items></response>");
|
||||
$act = $this->h->dispatch($this->req("api=xml"));
|
||||
$this->assertMessage($exp, $act);
|
||||
$this->assertMessage($exp, $this->req("api=xml"));
|
||||
}
|
||||
|
||||
public function testListFeedIcons(): void {
|
||||
$iconType = (new \ReflectionClassConstant(API::class, "GENERIC_ICON_TYPE"))->getValue();
|
||||
$iconData = (new \ReflectionClassConstant(API::class, "GENERIC_ICON_DATA"))->getValue();
|
||||
\Phake::when(Arsse::$db)->iconList->thenReturn(new Result($this->v([
|
||||
$this->dbMock->iconList->returns(new Result($this->v([
|
||||
['id' => 42, 'type' => "image/svg+xml", 'data' => "<svg/>"],
|
||||
['id' => 44, 'type' => null, 'data' => "IMAGE DATA"],
|
||||
['id' => 47, 'type' => null, 'data' => null],
|
||||
])));
|
||||
$act = $this->h->dispatch($this->req("api&favicons"));
|
||||
$exp = new JsonResponse(['favicons' => [
|
||||
['id' => 0, 'data' => $iconType.",".$iconData],
|
||||
['id' => 42, 'data' => "image/svg+xml;base64,PHN2Zy8+"],
|
||||
['id' => 44, 'data' => "application/octet-stream;base64,SU1BR0UgREFUQQ=="],
|
||||
]]);
|
||||
$this->assertMessage($exp, $act);
|
||||
$this->assertMessage($exp, $this->req("api&favicons"));
|
||||
}
|
||||
|
||||
public function testAnswerOptionsRequest(): void {
|
||||
$act = $this->h->dispatch($this->req("api", "", "OPTIONS"));
|
||||
$exp = new EmptyResponse(204, [
|
||||
'Allow' => "POST",
|
||||
'Accept' => "application/x-www-form-urlencoded, multipart/form-data",
|
||||
]);
|
||||
$this->assertMessage($exp, $act);
|
||||
$this->assertMessage($exp, $this->req("api", "", "OPTIONS"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
protected $u;
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
// create a mock user manager
|
||||
Arsse::$user = \Phake::mock(User::class);
|
||||
|
@ -31,10 +31,6 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->u = new FeverUser();
|
||||
}
|
||||
|
||||
public function tearDown(): void {
|
||||
self::clearData();
|
||||
}
|
||||
|
||||
/** @dataProvider providePasswordCreations */
|
||||
public function testRegisterAUserPassword(string $user, string $password = null, $exp): void {
|
||||
\Phake::when(Arsse::$user)->generatePassword->thenReturn("RANDOM_PASSWORD");
|
||||
|
|
|
@ -21,7 +21,7 @@ class TestToken extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
protected $transaction;
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
// create a mock database interface
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
|
@ -30,10 +30,6 @@ class TestToken extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->h = new Token();
|
||||
}
|
||||
|
||||
public function tearDown(): void {
|
||||
self::clearData();
|
||||
}
|
||||
|
||||
protected function v($value) {
|
||||
return $value;
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
// create a mock database interface
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
|
@ -85,10 +85,6 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->h = new V1();
|
||||
}
|
||||
|
||||
public function tearDown(): void {
|
||||
self::clearData();
|
||||
}
|
||||
|
||||
protected function v($value) {
|
||||
return $value;
|
||||
}
|
||||
|
|
|
@ -312,7 +312,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
// create a mock user manager
|
||||
Arsse::$user = \Phake::mock(User::class);
|
||||
|
@ -326,10 +326,6 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->h = new V1_2();
|
||||
}
|
||||
|
||||
public function tearDown(): void {
|
||||
self::clearData();
|
||||
}
|
||||
|
||||
protected function v($value) {
|
||||
return $value;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ use Laminas\Diactoros\Response\EmptyResponse;
|
|||
/** @covers \JKingWeb\Arsse\REST\NextcloudNews\Versions */
|
||||
class TestVersions extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
protected function req(string $method, string $target): ResponseInterface {
|
||||
|
|
|
@ -63,11 +63,12 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function testAuthenticateRequests(array $serverParams, array $expAttr): void {
|
||||
$r = new REST();
|
||||
// create a mock user manager
|
||||
Arsse::$user = \Phake::mock(User::class);
|
||||
\Phake::when(Arsse::$user)->auth->thenReturn(false);
|
||||
\Phake::when(Arsse::$user)->auth("john.doe@example.com", "secret")->thenReturn(true);
|
||||
\Phake::when(Arsse::$user)->auth("john.doe@example.com", "")->thenReturn(true);
|
||||
\Phake::when(Arsse::$user)->auth("someone.else@example.com", "")->thenReturn(true);
|
||||
$this->userMock = $this->mock(User::class);
|
||||
$this->userMock->auth->returns(false);
|
||||
$this->userMock->auth->with("john.doe@example.com", "secret")->returns(true);
|
||||
$this->userMock->auth->with("john.doe@example.com", "")->returns(true);
|
||||
$this->userMock->auth->with("someone.else@example.com", "")->returns(true);
|
||||
Arsse::$user = $this->userMock->get();
|
||||
// create an input server request
|
||||
$req = new ServerRequest($serverParams);
|
||||
// create the expected output
|
||||
|
@ -150,13 +151,13 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
/** @dataProvider provideCorsNegotiations */
|
||||
public function testNegotiateCors($origin, bool $exp, string $allowed = null, string $denied = null): void {
|
||||
self::setConf();
|
||||
$r = \Phake::partialMock(REST::class);
|
||||
\Phake::when($r)->corsNormalizeOrigin->thenReturnCallback(function($origin) {
|
||||
$rMock = $this->partialMock(REST::class);
|
||||
$rMock->corsNormalizeOrigin->does(function($origin) {
|
||||
return $origin;
|
||||
});
|
||||
$headers = isset($origin) ? ['Origin' => $origin] : [];
|
||||
$req = new Request("", "GET", "php://memory", $headers);
|
||||
$act = $r->corsNegotiate($req, $allowed, $denied);
|
||||
$act = $rMock->get()->corsNegotiate($req, $allowed, $denied);
|
||||
$this->assertSame($exp, $act);
|
||||
}
|
||||
|
||||
|
@ -251,15 +252,15 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
/** @dataProvider provideUnnormalizedResponses */
|
||||
public function testNormalizeHttpResponses(ResponseInterface $res, ResponseInterface $exp, RequestInterface $req = null): void {
|
||||
$r = \Phake::partialMock(REST::class);
|
||||
\Phake::when($r)->corsNegotiate->thenReturn(true);
|
||||
\Phake::when($r)->challenge->thenReturnCallback(function($res) {
|
||||
$rMock = $this->partialMock(REST::class);
|
||||
$rMock->corsNegotiate->returns(true);
|
||||
$rMock->challenge->does(function($res) {
|
||||
return $res->withHeader("WWW-Authenticate", "Fake Value");
|
||||
});
|
||||
\Phake::when($r)->corsApply->thenReturnCallback(function($res) {
|
||||
$rMock->corsApply->does(function($res) {
|
||||
return $res;
|
||||
});
|
||||
$act = $r->normalizeResponse($res, $req);
|
||||
$act = $rMock->get()->normalizeResponse($res, $req);
|
||||
$this->assertMessage($exp, $act);
|
||||
}
|
||||
|
||||
|
@ -287,30 +288,32 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
/** @dataProvider provideMockRequests */
|
||||
public function testDispatchRequests(ServerRequest $req, string $method, bool $called, string $class = "", string $target = ""): void {
|
||||
$r = \Phake::partialMock(REST::class);
|
||||
\Phake::when($r)->normalizeResponse->thenReturnCallback(function($res) {
|
||||
$rMock = $this->partialMock(REST::class);
|
||||
$rMock->normalizeResponse->does(function($res) {
|
||||
return $res;
|
||||
});
|
||||
\Phake::when($r)->authenticateRequest->thenReturnCallback(function($req) {
|
||||
$rMock->authenticateRequest->does(function($req) {
|
||||
return $req;
|
||||
});
|
||||
if ($called) {
|
||||
$h = \Phake::mock($class);
|
||||
\Phake::when(Arsse::$obj)->get($class)->thenReturn($h);
|
||||
\Phake::when($h)->dispatch->thenReturn(new EmptyResponse(204));
|
||||
$hMock = $this->mock($class);
|
||||
$hMock->dispatch->returns(new EmptyResponse(204));
|
||||
$this->objMock->get->with($class)->returns($hMock);
|
||||
Arsse::$obj = $this->objMock->get();
|
||||
}
|
||||
$out = $r->dispatch($req);
|
||||
$out = $rMock->get()->dispatch($req);
|
||||
$this->assertInstanceOf(ResponseInterface::class, $out);
|
||||
if ($called) {
|
||||
\Phake::verify($r)->authenticateRequest;
|
||||
\Phake::verify($h)->dispatch(\Phake::capture($in));
|
||||
$rMock->authenticateRequest->called();
|
||||
$hMock->dispatch->once()->called();
|
||||
$in = $hMock->dispatch->firstCall()->argument();;
|
||||
$this->assertSame($method, $in->getMethod());
|
||||
$this->assertSame($target, $in->getRequestTarget());
|
||||
} else {
|
||||
$this->assertSame(501, $out->getStatusCode());
|
||||
}
|
||||
\Phake::verify($r)->apiMatch;
|
||||
\Phake::verify($r)->normalizeResponse;
|
||||
$rMock->apiMatch->called();
|
||||
$rMock->normalizeResponse->called();
|
||||
}
|
||||
|
||||
public function provideMockRequests(): iterable {
|
||||
|
|
|
@ -20,7 +20,7 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
protected $user = "john.doe@example.com";
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
// create a mock user manager
|
||||
Arsse::$user = \Phake::mock(User::class);
|
||||
|
@ -29,10 +29,6 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->h = new Icon();
|
||||
}
|
||||
|
||||
public function tearDown(): void {
|
||||
self::clearData();
|
||||
}
|
||||
|
||||
protected function req(string $target, string $method = "GET", string $user = null): ResponseInterface {
|
||||
$prefix = "/tt-rss/feed-icons/";
|
||||
$url = $prefix.$target;
|
||||
|
|
|
@ -14,7 +14,7 @@ use JKingWeb\Arsse\Service\Serial\Driver;
|
|||
/** @covers \JKingWeb\Arsse\Service\Serial\Driver */
|
||||
class TestSerial extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ class TestService extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
protected $srv;
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
$this->srv = new Service();
|
||||
|
|
|
@ -13,7 +13,7 @@ use JKingWeb\Arsse\Service\Subprocess\Driver;
|
|||
/** @covers \JKingWeb\Arsse\Service\Subprocess\Driver */
|
||||
class TestSubprocess extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
}
|
||||
|
||||
|
|
|
@ -17,22 +17,23 @@ class TestArsse extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
public function setUp(): void {
|
||||
self::clearData(false);
|
||||
}
|
||||
public function tearDown(): void {
|
||||
self::clearData();
|
||||
}
|
||||
|
||||
public function testLoadExistingData(): void {
|
||||
$lang = Arsse::$lang = \Phake::mock(Lang::class);
|
||||
$db = Arsse::$db = \Phake::mock(Database::class);
|
||||
$user = Arsse::$user = \Phake::mock(User::class);
|
||||
$conf1 = Arsse::$conf = \Phake::mock(Conf::class);
|
||||
$lang = $this->mock(Lang::class);
|
||||
$db = $this->mock(Database::class);
|
||||
$user = $this->mock(User::class);
|
||||
$conf1 = $this->mock(Conf::class);
|
||||
Arsse::$lang = $lang->get();
|
||||
Arsse::$db = $db->get();
|
||||
Arsse::$user = $user->get();
|
||||
Arsse::$conf = $conf1->get();
|
||||
$conf2 = (new Conf)->import(['lang' => "test"]);
|
||||
Arsse::load($conf2);
|
||||
$this->assertSame($conf2, Arsse::$conf);
|
||||
$this->assertSame($lang, Arsse::$lang);
|
||||
$this->assertSame($db, Arsse::$db);
|
||||
$this->assertSame($user, Arsse::$user);
|
||||
\Phake::verify($lang)->set("test");
|
||||
$this->assertSame($lang->get(), Arsse::$lang);
|
||||
$this->assertSame($db->get(), Arsse::$db);
|
||||
$this->assertSame($user->get(), Arsse::$user);
|
||||
$lang->set->calledWith("test");
|
||||
}
|
||||
|
||||
public function testLoadNewData(): void {
|
||||
|
|
|
@ -14,7 +14,7 @@ use JKingWeb\Arsse\User\Internal\Driver;
|
|||
/** @covers \JKingWeb\Arsse\User\Internal\Driver */
|
||||
class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
// create a mock database interface
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
|
|
|
@ -17,7 +17,7 @@ use JKingWeb\Arsse\User\Driver;
|
|||
/** @covers \JKingWeb\Arsse\User */
|
||||
class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
parent::setUp();
|
||||
self::setConf();
|
||||
// create a mock database interface
|
||||
Arsse::$db = \Phake::mock(Database::class);
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
declare(strict_types=1);
|
||||
namespace JKingWeb\Arsse\Test;
|
||||
|
||||
use Eloquent\Phony\Mock\Handle\InstanceHandle;
|
||||
use Eloquent\Phony\Phpunit\Phony;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Exception\RequestException;
|
||||
use JKingWeb\Arsse\Exception;
|
||||
|
@ -29,12 +31,20 @@ use Laminas\Diactoros\Response\XmlResponse;
|
|||
abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
||||
use \DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
|
||||
|
||||
protected $objMock;
|
||||
protected $confMock;
|
||||
protected $langMock;
|
||||
protected $dbMock;
|
||||
protected $userMock;
|
||||
|
||||
|
||||
public function setUp(): void {
|
||||
self::clearData();
|
||||
}
|
||||
|
||||
public function tearDown(): void {
|
||||
self::clearData();
|
||||
// create the object factory as a mock
|
||||
$this->objMock = Arsse::$obj = $this->mock(Factory::class);
|
||||
$this->objMock->get->does(function(string $class) {
|
||||
return new $class;
|
||||
});
|
||||
}
|
||||
|
||||
public static function clearData(bool $loadLang = true): void {
|
||||
|
@ -46,11 +56,6 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
}
|
||||
if ($loadLang) {
|
||||
Arsse::$lang = new \JKingWeb\Arsse\Lang();
|
||||
// also create the object factory as a mock
|
||||
Arsse::$obj = \Phake::mock(Factory::class);
|
||||
\Phake::when(Arsse::$obj)->get->thenReturnCallback(function(string $class) {
|
||||
return new $class;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -340,12 +345,20 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
/** Guzzle's exception classes require some fairly complicated construction; this abstracts it all away so that only message and code need be supplied */
|
||||
protected function mockGuzzleException(string $class, ?string $message = null, ?int $code = null, ?\Throwable $e = null): GuzzleException {
|
||||
if (is_a($class, RequestException::class, true)) {
|
||||
$req = \Phake::mock(RequestInterface::class);
|
||||
$res = \Phake::mock(ResponseInterface::class);
|
||||
\Phake::when($res)->getStatusCode->thenReturn($code ?? 0);
|
||||
return new $class($message ?? "", $req, $res, $e);
|
||||
$req = $this->mock(RequestInterface::class);
|
||||
$res = $this->mock(ResponseInterface::class);
|
||||
$res->getStatusCode->returns($code ?? 0);
|
||||
return new $class($message ?? "", $req->get(), $res->get(), $e);
|
||||
} else {
|
||||
return new $class($message ?? "", $code ?? 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
protected function mock(string $class): InstanceHandle {
|
||||
return Phony::mock($class);
|
||||
}
|
||||
|
||||
protected function partialMock(string $class, ...$argument): InstanceHandle {
|
||||
return Phony::partialMock($class, $argument);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"phake/phake": "^3.0",
|
||||
"clue/arguments": "^2.0",
|
||||
"mikey179/vfsstream": "^1.6",
|
||||
"webmozart/glob": "^4.1"
|
||||
"webmozart/glob": "^4.1",
|
||||
"eloquent/phony-phpunit": "^6.0 || ^7.0"
|
||||
}
|
||||
}
|
||||
|
|
149
vendor-bin/phpunit/composer.lock
generated
149
vendor-bin/phpunit/composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "9c0d657e9fcab3d3be0467bbdc300a0a",
|
||||
"content-hash": "fda9bd2446005dfe56a223890cad0849",
|
||||
"packages": [],
|
||||
"packages-dev": [
|
||||
{
|
||||
|
@ -188,6 +188,153 @@
|
|||
],
|
||||
"time": "2020-11-10T18:47:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "eloquent/phony",
|
||||
"version": "5.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/eloquent/phony.git",
|
||||
"reference": "f34d67d6db6b6f351ea7e8aa8066107e756ec26b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/eloquent/phony/zipball/f34d67d6db6b6f351ea7e8aa8066107e756ec26b",
|
||||
"reference": "f34d67d6db6b6f351ea7e8aa8066107e756ec26b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3 || ^8"
|
||||
},
|
||||
"require-dev": {
|
||||
"eloquent/code-style": "^1.0",
|
||||
"eloquent/phpstan-phony": "^0.7",
|
||||
"errors/exceptions": "^0.2",
|
||||
"ext-pdo": "*",
|
||||
"friendsofphp/php-cs-fixer": "^2",
|
||||
"hamcrest/hamcrest-php": "^2",
|
||||
"phpstan/extension-installer": "^1",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpstan/phpstan-phpunit": "^0.12",
|
||||
"phpunit/phpunit": "^9"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "5.1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Eloquent\\Phony\\": "src"
|
||||
},
|
||||
"files": [
|
||||
"src/initialize.php",
|
||||
"src/functions.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Erin Millard",
|
||||
"email": "ezzatron@gmail.com",
|
||||
"homepage": "http://ezzatron.com/"
|
||||
}
|
||||
],
|
||||
"description": "Mocks, stubs, and spies for PHP.",
|
||||
"homepage": "http://eloquent-software.com/phony/",
|
||||
"keywords": [
|
||||
"Double",
|
||||
"Dummy",
|
||||
"fake",
|
||||
"mock",
|
||||
"mocking",
|
||||
"spy",
|
||||
"stub",
|
||||
"stubbing",
|
||||
"test"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/eloquent/phony/issues",
|
||||
"source": "https://github.com/eloquent/phony/tree/5.0.2"
|
||||
},
|
||||
"time": "2021-02-17T01:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "eloquent/phony-phpunit",
|
||||
"version": "7.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/eloquent/phony-phpunit.git",
|
||||
"reference": "e77ff95ea6235211d4aae7e5f53488a5faebc2e0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/eloquent/phony-phpunit/zipball/e77ff95ea6235211d4aae7e5f53488a5faebc2e0",
|
||||
"reference": "e77ff95ea6235211d4aae7e5f53488a5faebc2e0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"eloquent/phony": "^5",
|
||||
"php": "^7.3 || ^8",
|
||||
"phpunit/phpunit": "^9"
|
||||
},
|
||||
"require-dev": {
|
||||
"eloquent/code-style": "^1",
|
||||
"eloquent/phpstan-phony": "^0.7",
|
||||
"errors/exceptions": "^0.2",
|
||||
"friendsofphp/php-cs-fixer": "^2",
|
||||
"phpstan/extension-installer": "^1",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpstan/phpstan-phpunit": "^0.12"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "7.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Eloquent\\Phony\\Phpunit\\": "src"
|
||||
},
|
||||
"files": [
|
||||
"src/initialize.php",
|
||||
"src/functions.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Erin Millard",
|
||||
"email": "ezzatron@gmail.com",
|
||||
"homepage": "http://ezzatron.com/"
|
||||
}
|
||||
],
|
||||
"description": "Phony for PHPUnit.",
|
||||
"homepage": "http://eloquent-software.com/phony/",
|
||||
"keywords": [
|
||||
"Double",
|
||||
"Dummy",
|
||||
"fake",
|
||||
"mock",
|
||||
"mocking",
|
||||
"spy",
|
||||
"stub",
|
||||
"stubbing",
|
||||
"test"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/eloquent/phony-phpunit/issues",
|
||||
"source": "https://github.com/eloquent/phony-phpunit/tree/7.1.0"
|
||||
},
|
||||
"time": "2020-12-21T09:36:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mikey179/vfsstream",
|
||||
"version": "v1.6.8",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"require-dev": {
|
||||
"consolidation/robo": "^2.2",
|
||||
"consolidation/robo": "^3.0",
|
||||
"pear/archive_tar": "^1.4"
|
||||
}
|
||||
}
|
||||
|
|
108
vendor-bin/robo/composer.lock
generated
108
vendor-bin/robo/composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "1bd6e46df17a215ef177f27dadac115f",
|
||||
"content-hash": "ee0b828426eaa5ff905ef60d9a4b9aca",
|
||||
"packages": [],
|
||||
"packages-dev": [
|
||||
{
|
||||
|
@ -235,51 +235,49 @@
|
|||
},
|
||||
{
|
||||
"name": "consolidation/robo",
|
||||
"version": "2.2.2",
|
||||
"version": "3.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/consolidation/Robo.git",
|
||||
"reference": "b365df174d9cfb0f5814e4f3275a1c558b17bc4c"
|
||||
"reference": "734620ad3f9bb457fda1a52338b42439115cf941"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/consolidation/Robo/zipball/b365df174d9cfb0f5814e4f3275a1c558b17bc4c",
|
||||
"reference": "b365df174d9cfb0f5814e4f3275a1c558b17bc4c",
|
||||
"url": "https://api.github.com/repos/consolidation/Robo/zipball/734620ad3f9bb457fda1a52338b42439115cf941",
|
||||
"reference": "734620ad3f9bb457fda1a52338b42439115cf941",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"consolidation/annotated-command": "^4.2.1",
|
||||
"consolidation/config": "^1.2.1|^2",
|
||||
"consolidation/log": "^1.1.1|^2.0.1",
|
||||
"consolidation/output-formatters": "^4.1.1",
|
||||
"consolidation/annotated-command": "^4.2.4",
|
||||
"consolidation/config": "^1.2.1|^2.0.1",
|
||||
"consolidation/log": "^1.1.1|^2.0.2",
|
||||
"consolidation/output-formatters": "^4.1.2",
|
||||
"consolidation/self-update": "^1.2",
|
||||
"league/container": "^2.4.1",
|
||||
"league/container": "^3.3.1",
|
||||
"php": ">=7.1.3",
|
||||
"symfony/console": "^4.4.11|^5",
|
||||
"symfony/event-dispatcher": "^4.4.11|^5",
|
||||
"symfony/filesystem": "^4.4.11|^5",
|
||||
"symfony/finder": "^4.4.11|^5",
|
||||
"symfony/process": "^4.4.11|^5",
|
||||
"symfony/yaml": "^4.0 || ^5.0"
|
||||
"symfony/console": "^4.4.19 || ^5",
|
||||
"symfony/event-dispatcher": "^4.4.19 || ^5",
|
||||
"symfony/filesystem": "^4.4.9 || ^5",
|
||||
"symfony/finder": "^4.4.9 || ^5",
|
||||
"symfony/process": "^4.4.9 || ^5",
|
||||
"symfony/yaml": "^4.4 || ^5"
|
||||
},
|
||||
"conflict": {
|
||||
"codegyre/robo": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"g1a/composer-test-scenarios": "^3",
|
||||
"natxet/cssmin": "3.0.4",
|
||||
"patchwork/jsqueeze": "^2",
|
||||
"pear/archive_tar": "^1.4.4",
|
||||
"php-coveralls/php-coveralls": "^2.2",
|
||||
"phpdocumentor/reflection-docblock": "^4.3.2",
|
||||
"phpunit/phpunit": "^6.5.14",
|
||||
"squizlabs/php_codesniffer": "^3"
|
||||
"phpunit/phpunit": "^7.5.20 | ^8",
|
||||
"squizlabs/php_codesniffer": "^3",
|
||||
"yoast/phpunit-polyfills": "^0.2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"henrikbjorn/lurker": "For monitoring filesystem changes in taskWatch",
|
||||
"natxet/cssmin": "For minifying CSS files in taskMinify",
|
||||
"patchwork/jsqueeze": "For minifying JS files in taskMinify",
|
||||
"pear/archive_tar": "Allows tar archives to be created and extracted in taskPack and taskExtract, respectively."
|
||||
"pear/archive_tar": "Allows tar archives to be created and extracted in taskPack and taskExtract, respectively.",
|
||||
"totten/lurkerlite": "For monitoring filesystem changes in taskWatch"
|
||||
},
|
||||
"bin": [
|
||||
"robo"
|
||||
|
@ -330,9 +328,9 @@
|
|||
"description": "Modern task runner",
|
||||
"support": {
|
||||
"issues": "https://github.com/consolidation/Robo/issues",
|
||||
"source": "https://github.com/consolidation/Robo/tree/2.2.2"
|
||||
"source": "https://github.com/consolidation/Robo/tree/3.0.3"
|
||||
},
|
||||
"time": "2020-12-18T22:09:18+00:00"
|
||||
"time": "2021-02-21T19:19:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "consolidation/self-update",
|
||||
|
@ -388,42 +386,6 @@
|
|||
},
|
||||
"time": "2020-04-13T02:49:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "container-interop/container-interop",
|
||||
"version": "1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/container-interop/container-interop.git",
|
||||
"reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8",
|
||||
"reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"psr/container": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Interop\\Container\\": "src/Interop/Container/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
|
||||
"homepage": "https://github.com/container-interop/container-interop",
|
||||
"support": {
|
||||
"issues": "https://github.com/container-interop/container-interop/issues",
|
||||
"source": "https://github.com/container-interop/container-interop/tree/master"
|
||||
},
|
||||
"abandoned": "psr/container",
|
||||
"time": "2017-02-14T19:40:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dflydev/dot-access-data",
|
||||
"version": "v1.1.0",
|
||||
|
@ -540,37 +502,39 @@
|
|||
},
|
||||
{
|
||||
"name": "league/container",
|
||||
"version": "2.5.0",
|
||||
"version": "3.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/container.git",
|
||||
"reference": "8438dc47a0674e3378bcce893a0a04d79a2c22b3"
|
||||
"reference": "40aed0f11d16bc23f9d04a27acc3549cd1bb42ab"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/container/zipball/8438dc47a0674e3378bcce893a0a04d79a2c22b3",
|
||||
"reference": "8438dc47a0674e3378bcce893a0a04d79a2c22b3",
|
||||
"url": "https://api.github.com/repos/thephpleague/container/zipball/40aed0f11d16bc23f9d04a27acc3549cd1bb42ab",
|
||||
"reference": "40aed0f11d16bc23f9d04a27acc3549cd1bb42ab",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"container-interop/container-interop": "^1.2",
|
||||
"php": "^5.4 || ^7.0 || ^8.0"
|
||||
"php": "^7.0 || ^8.0",
|
||||
"psr/container": "^1.0"
|
||||
},
|
||||
"provide": {
|
||||
"container-interop/container-interop-implementation": "^1.2",
|
||||
"psr/container-implementation": "^1.0"
|
||||
},
|
||||
"replace": {
|
||||
"orno/di": "~2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.36",
|
||||
"scrutinizer/ocular": "^1.3",
|
||||
"phpunit/phpunit": "^6.0",
|
||||
"roave/security-advisories": "dev-master",
|
||||
"scrutinizer/ocular": "^1.8",
|
||||
"squizlabs/php_codesniffer": "^3.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.x-dev",
|
||||
"dev-3.x": "3.x-dev",
|
||||
"dev-2.x": "2.x-dev",
|
||||
"dev-1.x": "1.x-dev"
|
||||
}
|
||||
|
@ -605,7 +569,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/container/issues",
|
||||
"source": "https://github.com/thephpleague/container/tree/2.5.0"
|
||||
"source": "https://github.com/thephpleague/container/tree/3.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -613,7 +577,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-22T09:20:06+00:00"
|
||||
"time": "2021-02-22T10:35:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pear/archive_tar",
|
||||
|
|
Loading…
Reference in a new issue