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

Remove last uses of Phake

This commit is contained in:
J. King 2021-03-01 18:01:25 -05:00
parent 75148bfbc6
commit 3a1fcaac39
11 changed files with 385 additions and 417 deletions

View file

@ -22,32 +22,37 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
parent::setUp();
self::setConf();
// create a mock user manager
Arsse::$user = \Phake::mock(User::class);
\Phake::when(Arsse::$user)->auth->thenReturn(true);
$this->userMock = $this->mock(User::class);
$this->userMock->auth->returns(true);
// create a mock database interface
Arsse::$db = \Phake::mock(Database::class);
\Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(Transaction::class));
$this->dbMock = $this->mock(Database::class);
$this->dbMock->begin->returns($this->mock(Transaction::class));
}
protected function prepTest(): FeverUser {
Arsse::$user = $this->userMock->get();
Arsse::$db = $this->dbMock->get();
// instantiate the handler
$this->u = new FeverUser();
return new FeverUser;
}
/** @dataProvider providePasswordCreations */
public function testRegisterAUserPassword(string $user, string $password = null, $exp): void {
\Phake::when(Arsse::$user)->generatePassword->thenReturn("RANDOM_PASSWORD");
\Phake::when(Arsse::$db)->tokenCreate->thenReturnCallback(function($user, $class, $id = null) {
$this->userMock->generatePassword->returns("RANDOM_PASSWORD");
$this->dbMock->tokenCreate->does(function($user, $class, $id = null) {
return $id ?? "RANDOM_TOKEN";
});
\Phake::when(Arsse::$db)->tokenCreate("john.doe@example.org", $this->anything(), $this->anything())->thenThrow(new UserException("doesNotExist"));
$this->dbMock->tokenCreate->with("john.doe@example.org", $this->anything(), $this->anything())->throws(new UserException("doesNotExist"));
try {
if ($exp instanceof \JKingWeb\Arsse\AbstractException) {
$this->assertException($exp);
$this->u->register($user, $password);
$this->prepTest()->register($user, $password);
} else {
$this->assertSame($exp, $this->u->register($user, $password));
$this->assertSame($exp, $this->prepTest()->register($user, $password));
}
} finally {
\Phake::verify(Arsse::$db)->tokenRevoke($user, "fever.login");
\Phake::verify(Arsse::$db)->tokenCreate($user, "fever.login", md5($user.":".($password ?? "RANDOM_PASSWORD")));
$this->dbMock->tokenRevoke->calledWith($user, "fever.login");
$this->dbMock->tokenCreate->calledWith($user, "fever.login", md5($user.":".($password ?? "RANDOM_PASSWORD")));
}
}
@ -63,20 +68,20 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
}
public function testUnregisterAUser(): void {
\Phake::when(Arsse::$db)->tokenRevoke->thenReturn(3);
$this->assertTrue($this->u->unregister("jane.doe@example.com"));
\Phake::verify(Arsse::$db)->tokenRevoke("jane.doe@example.com", "fever.login");
\Phake::when(Arsse::$db)->tokenRevoke->thenReturn(0);
$this->assertFalse($this->u->unregister("john.doe@example.com"));
\Phake::verify(Arsse::$db)->tokenRevoke("john.doe@example.com", "fever.login");
$this->dbMock->tokenRevoke->returns(3);
$this->assertTrue($this->prepTest()->unregister("jane.doe@example.com"));
$this->dbMock->tokenRevoke->calledWith("jane.doe@example.com", "fever.login");
$this->dbMock->tokenRevoke->returns(0);
$this->assertFalse($this->prepTest()->unregister("john.doe@example.com"));
$this->dbMock->tokenRevoke->calledWith("john.doe@example.com", "fever.login");
}
/** @dataProvider provideUserAuthenticationRequests */
public function testAuthenticateAUserName(string $user, string $password, bool $exp): void {
\Phake::when(Arsse::$db)->tokenLookup->thenThrow(new ExceptionInput("constraintViolation"));
\Phake::when(Arsse::$db)->tokenLookup("fever.login", md5("jane.doe@example.com:secret"))->thenReturn(['user' => "jane.doe@example.com"]);
\Phake::when(Arsse::$db)->tokenLookup("fever.login", md5("john.doe@example.com:superman"))->thenReturn(['user' => "john.doe@example.com"]);
$this->assertSame($exp, $this->u->authenticate($user, $password));
$this->dbMock->tokenLookup->throws(new ExceptionInput("constraintViolation"));
$this->dbMock->tokenLookup->with("fever.login", md5("jane.doe@example.com:secret"))->returns(['user' => "jane.doe@example.com"]);
$this->dbMock->tokenLookup->with("fever.login", md5("john.doe@example.com:superman"))->returns(['user' => "john.doe@example.com"]);
$this->assertSame($exp, $this->prepTest()->authenticate($user, $password));
}
public function provideUserAuthenticationRequests(): iterable {

View file

@ -17,17 +17,21 @@ class TestToken extends \JKingWeb\Arsse\Test\AbstractTest {
protected const NOW = "2020-12-09T22:35:10.023419Z";
protected const TOKEN = "Tk2o9YubmZIL2fm2w8Z4KlDEQJz532fNSOcTG0s2_xc=";
protected $h;
protected $transaction;
public function setUp(): void {
parent::setUp();
self::setConf();
// create a mock database interface
Arsse::$db = \Phake::mock(Database::class);
$this->transaction = \Phake::mock(Transaction::class);
\Phake::when(Arsse::$db)->begin->thenReturn($this->transaction);
$this->h = new Token();
$this->dbMock = $this->mock(Database::class);
$this->transaction = $this->mock(Transaction::class);
$this->dbMock->begin->returns($this->transaction);
}
protected function prepTest(): Token {
Arsse::$db = $this->dbMock->get();
// instantiate the handler
return new Token;
}
protected function v($value) {
@ -35,9 +39,10 @@ class TestToken extends \JKingWeb\Arsse\Test\AbstractTest {
}
public function testGenerateTokens(): void {
\Phake::when(Arsse::$db)->tokenCreate->thenReturn("RANDOM TOKEN");
$this->assertSame("RANDOM TOKEN", $this->h->tokenGenerate("ook", "Eek"));
\Phake::verify(Arsse::$db)->tokenCreate("ook", "miniflux.login", \Phake::capture($token), null, "Eek");
$this->dbMock->tokenCreate->returns("RANDOM TOKEN");
$this->assertSame("RANDOM TOKEN", $this->prepTest()->tokenGenerate("ook", "Eek"));
$this->dbMock->tokenCreate->calledWith("ook", "miniflux.login", "~", null, "Eek");
$token = $this->dbMock->tokenCreate->firstCall()->argument(2);
$this->assertRegExp("/^[A-Za-z0-9_\-]{43}=$/", $token);
}
@ -52,15 +57,15 @@ class TestToken extends \JKingWeb\Arsse\Test\AbstractTest {
['label' => "Eek", 'id' => "TOKEN 2"],
['label' => "Ack", 'id' => "TOKEN 3"],
];
\Phake::when(Arsse::$db)->tokenList->thenReturn(new Result($this->v($out)));
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
$this->assertSame($exp, $this->h->tokenList("john.doe@example.com"));
\Phake::verify(Arsse::$db)->tokenList("john.doe@example.com", "miniflux.login");
$this->dbMock->tokenList->returns(new Result($this->v($out)));
$this->dbMock->userExists->returns(true);
$this->assertSame($exp, $this->prepTest()->tokenList("john.doe@example.com"));
$this->dbMock->tokenList->calledWith("john.doe@example.com", "miniflux.login");
}
public function testListTheTokensOfAMissingUser(): void {
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
$this->dbMock->userExists->returns(false);
$this->assertException("doesNotExist", "User", "ExceptionConflict");
$this->h->tokenList("john.doe@example.com");
$this->prepTest()->tokenList("john.doe@example.com");
}
}

View file

@ -22,14 +22,14 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
public function setUp(): void {
parent::setUp();
self::setConf();
// create a mock user manager
Arsse::$user = \Phake::mock(User::class);
Arsse::$user = $this->mock(User::class)->get();
// create a mock database interface
Arsse::$db = \Phake::mock(Database::class);
$this->dbMock = $this->mock(Database::class);
$this->h = new Icon();
}
protected function req(string $target, string $method = "GET", string $user = null): ResponseInterface {
Arsse::$db = $this->dbMock->get();
$prefix = "/tt-rss/feed-icons/";
$url = $prefix.$target;
$req = $this->serverRequest($method, $url, $prefix, [], [], null, "", [], $user);
@ -45,11 +45,11 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
}
public function testRetrieveFavion(): void {
\Phake::when(Arsse::$db)->subscriptionIcon->thenReturn(['url' => null]);
\Phake::when(Arsse::$db)->subscriptionIcon($this->anything(), 1123, false)->thenThrow(new ExceptionInput("subjectMissing"));
\Phake::when(Arsse::$db)->subscriptionIcon($this->anything(), 42, false)->thenReturn(['url' => "http://example.com/favicon.ico"]);
\Phake::when(Arsse::$db)->subscriptionIcon($this->anything(), 2112, false)->thenReturn(['url' => "http://example.net/logo.png"]);
\Phake::when(Arsse::$db)->subscriptionIcon($this->anything(), 1337, false)->thenReturn(['url' => "http://example.org/icon.gif\r\nLocation: http://bad.example.com/"]);
$this->dbMock->subscriptionIcon->returns(['url' => null]);
$this->dbMock->subscriptionIcon->with($this->anything(), 1123, false)->throws(new ExceptionInput("subjectMissing"));
$this->dbMock->subscriptionIcon->with($this->anything(), 42, false)->returns(['url' => "http://example.com/favicon.ico"]);
$this->dbMock->subscriptionIcon->with($this->anything(), 2112, false)->returns(['url' => "http://example.net/logo.png"]);
$this->dbMock->subscriptionIcon->with($this->anything(), 1337, false)->returns(['url' => "http://example.org/icon.gif\r\nLocation: http://bad.example.com/"]);
// these requests should succeed
$exp = new Response(301, ['Location' => "http://example.com/favicon.ico"]);
$this->assertMessage($exp, $this->req("42.ico"));
@ -71,13 +71,13 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
public function testRetrieveFavionWithHttpAuthentication(): void {
$url = ['url' => "http://example.org/icon.gif\r\nLocation: http://bad.example.com/"];
\Phake::when(Arsse::$db)->subscriptionIcon->thenReturn(['url' => null]);
\Phake::when(Arsse::$db)->subscriptionIcon($this->user, 42, false)->thenReturn($url);
\Phake::when(Arsse::$db)->subscriptionIcon("jane.doe", 2112, false)->thenReturn($url);
\Phake::when(Arsse::$db)->subscriptionIcon($this->user, 1337, false)->thenReturn($url);
\Phake::when(Arsse::$db)->subscriptionIcon(null, 42, false)->thenReturn($url);
\Phake::when(Arsse::$db)->subscriptionIcon(null, 2112, false)->thenReturn($url);
\Phake::when(Arsse::$db)->subscriptionIcon(null, 1337, false)->thenReturn($url);
$this->dbMock->subscriptionIcon->returns(['url' => null]);
$this->dbMock->subscriptionIcon->with($this->user, 42, false)->returns($url);
$this->dbMock->subscriptionIcon->with("jane.doe", 2112, false)->returns($url);
$this->dbMock->subscriptionIcon->with($this->user, 1337, false)->returns($url);
$this->dbMock->subscriptionIcon->with(null, 42, false)->returns($url);
$this->dbMock->subscriptionIcon->with(null, 2112, false)->returns($url);
$this->dbMock->subscriptionIcon->with(null, 1337, false)->returns($url);
// these requests should succeed
$exp = new Response(301, ['Location' => "http://example.org/icon.gif"]);
$this->assertMessage($exp, $this->req("42.ico"));

View file

@ -16,7 +16,8 @@ class TestSerial extends \JKingWeb\Arsse\Test\AbstractTest {
public function setUp(): void {
parent::setUp();
self::setConf();
Arsse::$db = \Phake::mock(Database::class);
$this->dbMock = $this->mock(Database::class);
Arsse::$db = $this->dbMock->get();
}
public function testConstruct(): void {
@ -40,8 +41,8 @@ class TestSerial extends \JKingWeb\Arsse\Test\AbstractTest {
$d = new Driver;
$d->queue(1, 4, 3);
$this->assertSame(Arsse::$conf->serviceQueueWidth, $d->exec());
\Phake::verify(Arsse::$db)->feedUpdate(1);
\Phake::verify(Arsse::$db)->feedUpdate(4);
\Phake::verify(Arsse::$db)->feedUpdate(3);
$this->dbMock->feedUpdate->calledWith(1);
$this->dbMock->feedUpdate->calledWith(4);
$this->dbMock->feedUpdate->calledWith(3);
}
}

View file

@ -18,14 +18,17 @@ class TestService extends \JKingWeb\Arsse\Test\AbstractTest {
public function setUp(): void {
parent::setUp();
self::setConf();
Arsse::$db = \Phake::mock(Database::class);
$this->dbMock = $this->mock(Database::class);
Arsse::$db = $this->dbMock->get();
$this->srv = new Service();
}
public function testCheckIn(): void {
$now = time();
$this->srv->checkIn();
\Phake::verify(Arsse::$db)->metaSet("service_last_checkin", \Phake::capture($then), "datetime");
$this->dbMock->metaSet->calledWith("service_last_checkin", "~", "datetime");
$then = $this->dbMock->metaSet->firstCall()->argument(1);
$this->assertTime($now, $then);
}
@ -35,51 +38,55 @@ class TestService extends \JKingWeb\Arsse\Test\AbstractTest {
$interval = Arsse::$conf->serviceFrequency;
$valid = (new \DateTimeImmutable("now", new \DateTimezone("UTC")))->sub($interval);
$invalid = $valid->sub($interval)->sub($interval);
\Phake::when(Arsse::$db)->metaGet("service_last_checkin")->thenReturn(Date::transform($valid, "sql"))->thenReturn(Date::transform($invalid, "sql"));
$this->dbMock->metaGet->with("service_last_checkin")->returns(Date::transform($valid, "sql"), Date::transform($invalid, "sql"));
Arsse::$db = $this->dbMock->get();
$this->assertTrue(Service::hasCheckedIn());
$this->assertFalse(Service::hasCheckedIn());
}
public function testPerformPreCleanup(): void {
$this->assertTrue(Service::cleanupPre());
\Phake::verify(Arsse::$db)->feedCleanup();
\Phake::verify(Arsse::$db)->iconCleanup();
\Phake::verify(Arsse::$db)->sessionCleanup();
$this->dbMock->feedCleanup->called();
$this->dbMock->iconCleanup->called();
$this->dbMock->sessionCleanup->called();
}
public function testPerformShortPostCleanup(): void {
\Phake::when(Arsse::$db)->articleCleanup()->thenReturn(0);
$this->dbMock->articleCleanup->returns(0);
Arsse::$db = $this->dbMock->get();
$this->assertTrue(Service::cleanupPost());
\Phake::verify(Arsse::$db)->articleCleanup();
\Phake::verify(Arsse::$db, \Phake::times(0))->driverMaintenance();
$this->dbMock->articleCleanup->Called();
$this->dbMock->driverMaintenance->never()->called();
}
public function testPerformFullPostCleanup(): void {
\Phake::when(Arsse::$db)->articleCleanup()->thenReturn(1);
$this->dbMock->articleCleanup->returns(1);
Arsse::$db = $this->dbMock->get();
$this->assertTrue(Service::cleanupPost());
\Phake::verify(Arsse::$db)->articleCleanup();
\Phake::verify(Arsse::$db)->driverMaintenance();
$this->dbMock->articleCleanup->called();
$this->dbMock->driverMaintenance->called();
}
public function testRefreshFeeds(): void {
// set up mock database actions
\Phake::when(Arsse::$db)->metaSet->thenReturn(true);
\Phake::when(Arsse::$db)->feedCleanup->thenReturn(true);
\Phake::when(Arsse::$db)->sessionCleanup->thenReturn(true);
\Phake::when(Arsse::$db)->articleCleanup->thenReturn(0);
\Phake::when(Arsse::$db)->feedListStale->thenReturn([1,2,3]);
$this->dbMock->metaSet->returns(true);
$this->dbMock->feedCleanup->returns(true);
$this->dbMock->sessionCleanup->returns(true);
$this->dbMock->articleCleanup->returns(0);
$this->dbMock->feedListStale->returns([1,2,3]);
// perform the test
$d = \Phake::mock(\JKingWeb\Arsse\Service\Driver::class);
$s = new \JKingWeb\Arsse\Test\Service($d);
Arsse::$db = $this->dbMock->get();
$d = $this->mock(\JKingWeb\Arsse\Service\Driver::class);
$s = new \JKingWeb\Arsse\Test\Service($d->get());
$this->assertInstanceOf(\DateTimeInterface::class, $s->watch(false));
// verify invocations
\Phake::verify($d)->queue(1, 2, 3);
\Phake::verify($d)->exec();
\Phake::verify($d)->clean();
\Phake::verify(Arsse::$db)->feedCleanup();
\Phake::verify(Arsse::$db)->iconCleanup();
\Phake::verify(Arsse::$db)->sessionCleanup();
\Phake::verify(Arsse::$db)->articleCleanup();
\Phake::verify(Arsse::$db)->metaSet("service_last_checkin", $this->anything(), "datetime");
$d->queue->calledWith(1, 2, 3);
$d->exec->called();
$d->clean->called();
$this->dbMock->feedCleanup->called();
$this->dbMock->iconCleanup->called();
$this->dbMock->sessionCleanup->called();
$this->dbMock->articleCleanup->called();
$this->dbMock->metaSet->calledWith("service_last_checkin", $this->anything(), "datetime");
}
}

View file

@ -35,13 +35,14 @@ class TestSubprocess extends \JKingWeb\Arsse\Test\AbstractTest {
}
public function testRefreshFeeds(): void {
$d = \Phake::partialMock(Driver::class);
\Phake::when($d)->execCmd->thenReturnCallback(function(string $cmd) {
$dMock = $this->partialMock(Driver::class);
$dMock->execCmd->does(function(string $cmd) {
// FIXME: Does this work in Windows?
return popen("echo ".escapeshellarg($cmd), "r");
});
$d = $dMock->get();
$this->assertSame(3, $d->queue(1, 4, 3));
$this->assertSame(Arsse::$conf->serviceQueueWidth, $d->exec());
\Phake::verify($d, \Phake::times(3))->execCmd;
$dMock->execCmd->times(3)->called();
}
}

View file

@ -17,8 +17,13 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
parent::setUp();
self::setConf();
// create a mock database interface
Arsse::$db = \Phake::mock(Database::class);
\Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(\JKingWeb\Arsse\Db\Transaction::class));
$this->dbMock = $this->mock(Database::class);
$this->dbMock->begin->returns($this->mock(\JKingWeb\Arsse\Db\Transaction::class));
}
protected function prepTest(): Driver {
Arsse::$db = $this->dbMock->get();
return new Driver;
}
public function testConstruct(): void {
@ -34,12 +39,12 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
* @group slow
*/
public function testAuthenticateAUser(string $user, $password, bool $exp): void {
\Phake::when(Arsse::$db)->userPasswordGet("john.doe@example.com")->thenReturn('$2y$10$1zbqRJhxM8uUjeSBPp4IhO90xrqK0XjEh9Z16iIYEFRV4U.zeAFom'); // hash of "secret"
\Phake::when(Arsse::$db)->userPasswordGet("jane.doe@example.com")->thenReturn('$2y$10$bK1ljXfTSyc2D.NYvT.Eq..OpehLRXVbglW.23ihVuyhgwJCd.7Im'); // hash of "superman"
\Phake::when(Arsse::$db)->userPasswordGet("owen.hardy@example.com")->thenReturn("");
\Phake::when(Arsse::$db)->userPasswordGet("kira.nerys@example.com")->thenThrow(new \JKingWeb\Arsse\User\ExceptionConflict("doesNotExist"));
\Phake::when(Arsse::$db)->userPasswordGet("007@example.com")->thenReturn(null);
$this->assertSame($exp, (new Driver)->auth($user, $password));
$this->dbMock->userPasswordGet->with("john.doe@example.com")->returns('$2y$10$1zbqRJhxM8uUjeSBPp4IhO90xrqK0XjEh9Z16iIYEFRV4U.zeAFom'); // hash of "secret"
$this->dbMock->userPasswordGet->with("jane.doe@example.com")->returns('$2y$10$bK1ljXfTSyc2D.NYvT.Eq..OpehLRXVbglW.23ihVuyhgwJCd.7Im'); // hash of "superman"
$this->dbMock->userPasswordGet->with("owen.hardy@example.com")->returns("");
$this->dbMock->userPasswordGet->with("kira.nerys@example.com")->throws(new \JKingWeb\Arsse\User\ExceptionConflict("doesNotExist"));
$this->dbMock->userPasswordGet->with("007@example.com")->returns(null);
$this->assertSame($exp, $this->prepTest()->auth($user, $password));
}
public function provideAuthentication(): iterable {
@ -68,115 +73,111 @@ class TestInternal extends \JKingWeb\Arsse\Test\AbstractTest {
public function testListUsers(): void {
$john = "john.doe@example.com";
$jane = "jane.doe@example.com";
\Phake::when(Arsse::$db)->userList->thenReturn([$john, $jane])->thenReturn([$jane, $john]);
$driver = new Driver;
$this->dbMock->userList->returns([$john, $jane])->returns([$jane, $john]);
$driver = $this->prepTest();
$this->assertSame([$john, $jane], $driver->userList());
$this->assertSame([$jane, $john], $driver->userList());
\Phake::verify(Arsse::$db, \Phake::times(2))->userList;
$this->dbMock->userList->times(2)->called();
}
public function testAddAUser(): void {
$john = "john.doe@example.com";
\Phake::when(Arsse::$db)->userAdd->thenReturnCallback(function($user, $pass) {
$this->dbMock->userAdd->does(function($user, $pass) {
return $pass;
});
$driver = new Driver;
$driver = $this->prepTest();
$this->assertNull($driver->userAdd($john));
$this->assertNull($driver->userAdd($john, null));
$this->assertSame("secret", $driver->userAdd($john, "secret"));
\Phake::verify(Arsse::$db)->userAdd($john, "secret");
\Phake::verify(Arsse::$db)->userAdd;
$this->dbMock->userAdd->calledWith($john, "secret");
$this->dbMock->userAdd->called();
}
public function testRenameAUser(): void {
$john = "john.doe@example.com";
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
$this->assertTrue((new Driver)->userRename($john, "jane.doe@example.com"));
$this->assertFalse((new Driver)->userRename($john, $john));
\Phake::verify(Arsse::$db, \Phake::times(2))->userExists($john);
$this->dbMock->userExists->returns(true);
$this->assertTrue($this->prepTest()->userRename($john, "jane.doe@example.com"));
$this->assertFalse($this->prepTest()->userRename($john, $john));
$this->dbMock->userExists->times(2)->calledWith($john);
}
public function testRenameAMissingUser(): void {
$john = "john.doe@example.com";
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
$this->dbMock->userExists->returns(false);
$this->assertException("doesNotExist", "User", "ExceptionConflict");
(new Driver)->userRename($john, "jane.doe@example.com");
$this->prepTest()->userRename($john, "jane.doe@example.com");
}
public function testRemoveAUser(): void {
$john = "john.doe@example.com";
\Phake::when(Arsse::$db)->userRemove->thenReturn(true)->thenThrow(new \JKingWeb\Arsse\User\ExceptionConflict("doesNotExist"));
$driver = new Driver;
$this->dbMock->userRemove->returns(true)->throws(new \JKingWeb\Arsse\User\ExceptionConflict("doesNotExist"));
$driver = $this->prepTest();
$this->assertTrue($driver->userRemove($john));
\Phake::verify(Arsse::$db, \Phake::times(1))->userRemove($john);
$this->dbMock->userRemove->calledWith($john);
$this->assertException("doesNotExist", "User", "ExceptionConflict");
try {
$this->assertFalse($driver->userRemove($john));
} finally {
\Phake::verify(Arsse::$db, \Phake::times(2))->userRemove($john);
$this->dbMock->userRemove->times(2)->calledWith($john);
}
}
public function testSetAPassword(): void {
$john = "john.doe@example.com";
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
$this->assertSame("superman", (new Driver)->userPasswordSet($john, "superman"));
$this->assertSame(null, (new Driver)->userPasswordSet($john, null));
\Phake::verify(Arsse::$db, \Phake::times(0))->userPasswordSet;
$this->dbMock->userExists->returns(true);
$this->assertSame("superman", $this->prepTest()->userPasswordSet($john, "superman"));
$this->assertSame(null, $this->prepTest()->userPasswordSet($john, null));
$this->dbMock->userPasswordSet->never()->called();
}
public function testSetAPasswordForAMssingUser(): void {
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
$this->dbMock->userExists->returns(false);
$this->assertException("doesNotExist", "User", "ExceptionConflict");
(new Driver)->userPasswordSet("john.doe@example.com", "secret");
$this->prepTest()->userPasswordSet("john.doe@example.com", "secret");
}
public function testUnsetAPassword(): void {
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
$this->assertTrue((new Driver)->userPasswordUnset("john.doe@example.com"));
\Phake::verify(Arsse::$db, \Phake::times(0))->userPasswordUnset;
$this->dbMock->userExists->returns(true);
$this->assertTrue($this->prepTest()->userPasswordUnset("john.doe@example.com"));
$this->dbMock->userPasswordSet->never()->called();
}
public function testUnsetAPasswordForAMssingUser(): void {
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
$this->dbMock->userExists->returns(false);
$this->assertException("doesNotExist", "User", "ExceptionConflict");
(new Driver)->userPasswordUnset("john.doe@example.com");
$this->prepTest()->userPasswordUnset("john.doe@example.com");
}
public function testGetUserProperties(): void {
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
$this->assertSame([], (new Driver)->userPropertiesGet("john.doe@example.com"));
\Phake::verify(Arsse::$db)->userExists("john.doe@example.com");
\Phake::verifyNoFurtherInteraction(Arsse::$db);
$this->dbMock->userExists->returns(true);
$this->assertSame([], $this->prepTest()->userPropertiesGet("john.doe@example.com"));
$this->dbMock->userExists->calledWith("john.doe@example.com");
}
public function testGetPropertiesForAMissingUser(): void {
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
$this->dbMock->userExists->returns(false);
$this->assertException("doesNotExist", "User", "ExceptionConflict");
try {
(new Driver)->userPropertiesGet("john.doe@example.com");
$this->prepTest()->userPropertiesGet("john.doe@example.com");
} finally {
\Phake::verify(Arsse::$db)->userExists("john.doe@example.com");
\Phake::verifyNoFurtherInteraction(Arsse::$db);
$this->dbMock->userExists->calledWith("john.doe@example.com");
}
}
public function testSetUserProperties(): void {
$in = ['admin' => true];
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
$this->assertSame($in, (new Driver)->userPropertiesSet("john.doe@example.com", $in));
\Phake::verify(Arsse::$db)->userExists("john.doe@example.com");
\Phake::verifyNoFurtherInteraction(Arsse::$db);
$this->dbMock->userExists->returns(true);
$this->assertSame($in, $this->prepTest()->userPropertiesSet("john.doe@example.com", $in));
$this->dbMock->userExists->calledWith("john.doe@example.com");
}
public function testSetPropertiesForAMissingUser(): void {
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
$this->dbMock->userExists->returns(false);
$this->assertException("doesNotExist", "User", "ExceptionConflict");
try {
(new Driver)->userPropertiesSet("john.doe@example.com", ['admin' => true]);
$this->prepTest()->userPropertiesSet("john.doe@example.com", ['admin' => true]);
} finally {
\Phake::verify(Arsse::$db)->userExists("john.doe@example.com");
\Phake::verifyNoFurtherInteraction(Arsse::$db);
$this->dbMock->userExists->calledWith("john.doe@example.com");
}
}
}

View file

@ -6,6 +6,7 @@
declare(strict_types=1);
namespace JKingWeb\Arsse\TestCase\User;
use Eloquent\Phony\Phpunit\Phony;
use JKingWeb\Arsse\Arsse;
use JKingWeb\Arsse\Database;
use JKingWeb\Arsse\User;
@ -20,19 +21,25 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
parent::setUp();
self::setConf();
// create a mock database interface
Arsse::$db = \Phake::mock(Database::class);
\Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(\JKingWeb\Arsse\Db\Transaction::class));
$this->dbMock= $this->mock(Database::class);
$this->dbMock->begin->returns($this->mock(\JKingWeb\Arsse\Db\Transaction::class));
// create a mock user driver
$this->drv = \Phake::mock(Driver::class);
$this->drv = $this->mock(Driver::class);
}
public function tearDown(): void {
\Phake::verifyNoOtherInteractions($this->drv);
\Phake::verifyNoOtherInteractions(Arsse::$db);
protected function prepTest(?\Closure $partialMockDef = null): User {
Arsse::$db = $this->dbMock->get();
if ($partialMockDef) {
$this->userMock = $this->partialMock(User::class, $this->drv->get());
$partialMockDef($this->userMock);
return $this->userMock->get();
} else {
return new User($this->drv->get());
}
}
public function testConstruct(): void {
$this->assertInstanceOf(User::class, new User($this->drv));
$this->assertInstanceOf(User::class, new User($this->drv->get()));
$this->assertInstanceOf(User::class, new User);
}
@ -45,14 +52,13 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
}
public function testStartATransaction(): void {
\Phake::when(Arsse::$db)->begin->thenReturn(\Phake::mock(Transaction::class));
$u = new User($this->drv);
$u = $this->prepTest();
$this->assertInstanceOf(Transaction::class, $u->begin());
\Phake::verify(Arsse::$db)->begin();
$this->dbMock->begin->calledWith();
}
public function testGeneratePasswords(): void {
$u = new User($this->drv);
$u = $this->prepTest();
$pass1 = $u->generatePassword();
$pass2 = $u->generatePassword();
$this->assertNotEquals($pass1, $pass2);
@ -61,18 +67,18 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
/** @dataProvider provideAuthentication */
public function testAuthenticateAUser(bool $preAuth, string $user, string $password, bool $exp): void {
Arsse::$conf->userPreAuth = $preAuth;
\Phake::when($this->drv)->auth->thenReturn(false);
\Phake::when($this->drv)->auth("john.doe@example.com", "secret")->thenReturn(true);
\Phake::when($this->drv)->auth("jane.doe@example.com", "superman")->thenReturn(true);
\Phake::when(Arsse::$db)->userExists("john.doe@example.com")->thenReturn(true);
\Phake::when(Arsse::$db)->userExists("jane.doe@example.com")->thenReturn(false);
\Phake::when(Arsse::$db)->userAdd->thenReturn("");
$u = new User($this->drv);
$this->drv->auth->returns(false);
$this->drv->auth->with("john.doe@example.com", "secret")->returns(true);
$this->drv->auth->with("jane.doe@example.com", "superman")->returns(true);
$this->dbMock->userExists->with("john.doe@example.com")->returns(true);
$this->dbMock->userExists->with("jane.doe@example.com")->returns(false);
$this->dbMock->userAdd->returns("");
$u = $this->prepTest();
$this->assertSame($exp, $u->auth($user, $password));
$this->assertNull($u->id);
\Phake::verify($this->drv, \Phake::times((int) !$preAuth))->auth($user, $password);
\Phake::verify(Arsse::$db, \Phake::times($exp ? 1 : 0))->userExists($user);
\Phake::verify(Arsse::$db, \Phake::times($exp && $user === "jane.doe@example.com" ? 1 : 0))->userAdd($user, $password);
$this->drv->auth->times((int) !$preAuth)->called();
$this->dbMock->userExists->times($exp ? 1 : 0)->calledWith($user);
$this->dbMock->userAdd->times($exp && $user === "jane.doe@example.com" ? 1 : 0)->calledWith($user, $password);
}
public function provideAuthentication(): iterable {
@ -92,77 +98,77 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
public function testListUsers(): void {
$exp = ["john.doe@example.com", "jane.doe@example.com"];
$u = new User($this->drv);
\Phake::when($this->drv)->userList->thenReturn(["john.doe@example.com", "jane.doe@example.com"]);
$this->drv->userList->returns(["john.doe@example.com", "jane.doe@example.com"]);
$u = $this->prepTest();
$this->assertSame($exp, $u->list());
\Phake::verify($this->drv)->userList();
$this->drv->userList->calledWith();
}
public function testLookUpAUserByNumber(): void {
$exp = "john.doe@example.com";
$u = new User($this->drv);
\Phake::when(Arsse::$db)->userLookup->thenReturn($exp);
$this->dbMock->userLookup->returns($exp);
$u = $this->prepTest();
$this->assertSame($exp, $u->lookup(2112));
\Phake::verify(Arsse::$db)->userLookup(2112);
$this->dbMock->userLookup->calledWith(2112);
}
public function testAddAUser(): void {
$user = "john.doe@example.com";
$pass = "secret";
$u = new User($this->drv);
\Phake::when($this->drv)->userAdd->thenReturn($pass);
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
$this->drv->userAdd->returns($pass);
$this->dbMock->userExists->returns(true);
$u = $this->prepTest();
$this->assertSame($pass, $u->add($user, $pass));
\Phake::verify($this->drv)->userAdd($user, $pass);
\Phake::verify(Arsse::$db)->userExists($user);
$this->drv->userAdd->calledWith($user, $pass);
$this->dbMock->userExists->calledWith($user);
}
public function testAddAUserWeDoNotKnow(): void {
$user = "john.doe@example.com";
$pass = "secret";
$u = new User($this->drv);
\Phake::when($this->drv)->userAdd->thenReturn($pass);
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
$this->drv->userAdd->returns($pass);
$this->dbMock->userExists->returns(false);
$u = $this->prepTest();
$this->assertSame($pass, $u->add($user, $pass));
\Phake::verify($this->drv)->userAdd($user, $pass);
\Phake::verify(Arsse::$db)->userExists($user);
\Phake::verify(Arsse::$db)->userAdd($user, $pass);
$this->drv->userAdd->calledWith($user, $pass);
$this->dbMock->userExists->calledWith($user);
$this->dbMock->userAdd->calledWith($user, $pass);
}
public function testAddADuplicateUser(): void {
$user = "john.doe@example.com";
$pass = "secret";
$u = new User($this->drv);
\Phake::when($this->drv)->userAdd->thenThrow(new ExceptionConflict("alreadyExists"));
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
$this->drv->userAdd->throws(new ExceptionConflict("alreadyExists"));
$this->dbMock->userExists->returns(true);
$u = $this->prepTest();
$this->assertException("alreadyExists", "User", "ExceptionConflict");
try {
$u->add($user, $pass);
} finally {
\Phake::verify(Arsse::$db)->userExists($user);
\Phake::verify($this->drv)->userAdd($user, $pass);
$this->dbMock->userExists->calledWith($user);
$this->drv->userAdd->calledWith($user, $pass);
}
}
public function testAddADuplicateUserWeDoNotKnow(): void {
$user = "john.doe@example.com";
$pass = "secret";
$u = new User($this->drv);
\Phake::when($this->drv)->userAdd->thenThrow(new ExceptionConflict("alreadyExists"));
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
$this->drv->userAdd->throws(new ExceptionConflict("alreadyExists"));
$this->dbMock->userExists->returns(false);
$u = $this->prepTest();
$this->assertException("alreadyExists", "User", "ExceptionConflict");
try {
$u->add($user, $pass);
} finally {
\Phake::verify(Arsse::$db)->userExists($user);
\Phake::verify(Arsse::$db)->userAdd($user, null);
\Phake::verify($this->drv)->userAdd($user, $pass);
$this->dbMock->userExists->calledWith($user);
$this->dbMock->userAdd->calledWith($user, null);
$this->drv->userAdd->calledWith($user, $pass);
}
}
/** @dataProvider provideInvalidUserNames */
public function testAddAnInvalidUser(string $user): void {
$u = new User($this->drv);
$u = $this->prepTest();
$this->assertException("invalidUsername", "User", "ExceptionInput");
$u->add($user, "secret");
}
@ -181,233 +187,237 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
public function testAddAUserWithARandomPassword(): void {
$user = "john.doe@example.com";
$pass = "random password";
$u = \Phake::partialMock(User::class, $this->drv);
\Phake::when($u)->generatePassword->thenReturn($pass);
\Phake::when($this->drv)->userAdd->thenReturn(null)->thenReturn($pass);
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
$this->drv->userAdd->returns(null)->returns($pass);
$this->dbMock->userExists->returns(true);
$u = $this->prepTest(function ($u) use ($pass) {
$u->generatePassword->returns($pass);
});
$this->assertSame($pass, $u->add($user));
\Phake::verify($this->drv)->userAdd($user, null);
\Phake::verify($this->drv)->userAdd($user, $pass);
\Phake::verify(Arsse::$db)->userExists($user);
$this->drv->userAdd->calledWith($user, null);
$this->drv->userAdd->calledWith($user, $pass);
$this->dbMock->userExists->calledWith($user);
}
public function testRenameAUser(): void {
$tr = \Phake::mock(Transaction::class);
\Phake::when(Arsse::$db)->begin->thenReturn($tr);
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
\Phake::when(Arsse::$db)->userAdd->thenReturn(true);
\Phake::when(Arsse::$db)->userRename->thenReturn(true);
\Phake::when($this->drv)->userRename->thenReturn(true);
$u = new User($this->drv);
$tr = $this->mock(Transaction::class);
$this->dbMock->begin->returns($tr);
$this->dbMock->userExists->returns(true);
$this->dbMock->userAdd->returns(true);
$this->dbMock->userRename->returns(true);
$this->drv->userRename->returns(true);
$u = $this->prepTest();
$old = "john.doe@example.com";
$new = "jane.doe@example.com";
$this->assertTrue($u->rename($old, $new));
\Phake::inOrder(
\Phake::verify($this->drv)->userRename($old, $new),
\Phake::verify(Arsse::$db)->begin(),
\Phake::verify(Arsse::$db)->userExists($old),
\Phake::verify(Arsse::$db)->userRename($old, $new),
\Phake::verify(Arsse::$db)->sessionDestroy($new),
\Phake::verify(Arsse::$db)->tokenRevoke($new, "fever.login"),
\Phake::verify($tr)->commit()
Phony::inOrder(
$this->drv->userRename->calledWith($old, $new),
$this->dbMock->begin->calledWith(),
$this->dbMock->userExists->calledWith($old),
$this->dbMock->userRename->calledWith($old, $new),
$this->dbMock->sessionDestroy->calledWith($new),
$this->dbMock->tokenRevoke->calledWith($new, "fever.login"),
$tr->commit->called()
);
}
public function testRenameAUserWeDoNotKnow(): void {
$tr = \Phake::mock(Transaction::class);
\Phake::when(Arsse::$db)->begin->thenReturn($tr);
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
\Phake::when(Arsse::$db)->userAdd->thenReturn(true);
\Phake::when(Arsse::$db)->userRename->thenReturn(true);
\Phake::when($this->drv)->userRename->thenReturn(true);
$u = new User($this->drv);
$tr = $this->mock(Transaction::class);
$this->dbMock->begin->returns($tr);
$this->dbMock->userExists->returns(false);
$this->dbMock->userAdd->returns(true);
$this->dbMock->userRename->returns(true);
$this->drv->userRename->returns(true);
$u = $this->prepTest();
$old = "john.doe@example.com";
$new = "jane.doe@example.com";
$this->assertTrue($u->rename($old, $new));
\Phake::inOrder(
\Phake::verify($this->drv)->userRename($old, $new),
\Phake::verify(Arsse::$db)->begin(),
\Phake::verify(Arsse::$db)->userExists($old),
\Phake::verify(Arsse::$db)->userAdd($new, null),
\Phake::verify($tr)->commit()
Phony::inOrder(
$this->drv->userRename->calledWith($old, $new),
$this->dbMock->begin->calledWith(),
$this->dbMock->userExists->calledWith($old),
$this->dbMock->userAdd->calledWith($new, null),
$tr->commit->called()
);
}
public function testRenameAUserWithoutEffect(): void {
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
\Phake::when(Arsse::$db)->userAdd->thenReturn(true);
\Phake::when(Arsse::$db)->userRename->thenReturn(true);
\Phake::when($this->drv)->userRename->thenReturn(false);
$u = new User($this->drv);
$this->dbMock->userExists->returns(false);
$this->dbMock->userAdd->returns(true);
$this->dbMock->userRename->returns(true);
$this->drv->userRename->returns(false);
$u = $this->prepTest();
$old = "john.doe@example.com";
$this->assertFalse($u->rename($old, $old));
\Phake::verify($this->drv)->userRename($old, $old);
$this->drv->userRename->calledWith($old, $old);
}
/** @dataProvider provideInvalidUserNames */
public function testRenameAUserToAnInvalidName(string $new): void {
$u = new User($this->drv);
$u = $this->prepTest();
$this->assertException("invalidUsername", "User", "ExceptionInput");
$u->rename("john.doe@example.com", $new);
}
public function testRemoveAUser(): void {
$user = "john.doe@example.com";
$u = new User($this->drv);
\Phake::when($this->drv)->userRemove->thenReturn(true);
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
$this->drv->userRemove->returns(true);
$this->dbMock->userExists->returns(true);
$u = $this->prepTest();
$this->assertTrue($u->remove($user));
\Phake::verify(Arsse::$db)->userExists($user);
\Phake::verify(Arsse::$db)->userRemove($user);
\Phake::verify($this->drv)->userRemove($user);
$this->dbMock->userExists->calledWith($user);
$this->dbMock->userRemove->calledWith($user);
$this->drv->userRemove->calledWith($user);
}
public function testRemoveAUserWeDoNotKnow(): void {
$user = "john.doe@example.com";
$u = new User($this->drv);
\Phake::when($this->drv)->userRemove->thenReturn(true);
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
$this->drv->userRemove->returns(true);
$this->dbMock->userExists->returns(false);
$u = $this->prepTest();
$this->assertTrue($u->remove($user));
\Phake::verify(Arsse::$db)->userExists($user);
\Phake::verify($this->drv)->userRemove($user);
$this->dbMock->userExists->calledWith($user);
$this->drv->userRemove->calledWith($user);
}
public function testRemoveAMissingUser(): void {
$user = "john.doe@example.com";
$pass = "secret";
$u = new User($this->drv);
\Phake::when($this->drv)->userRemove->thenThrow(new ExceptionConflict("doesNotExist"));
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
$this->drv->userRemove->throws(new ExceptionConflict("doesNotExist"));
$this->dbMock->userExists->returns(true);
$u = $this->prepTest();
$this->assertException("doesNotExist", "User", "ExceptionConflict");
try {
$u->remove($user);
} finally {
\Phake::verify(Arsse::$db)->userExists($user);
\Phake::verify(Arsse::$db)->userRemove($user);
\Phake::verify($this->drv)->userRemove($user);
$this->dbMock->userExists->calledWith($user);
$this->dbMock->userRemove->calledWith($user);
$this->drv->userRemove->calledWith($user);
}
}
public function testRemoveAMissingUserWeDoNotKnow(): void {
$user = "john.doe@example.com";
$pass = "secret";
$u = new User($this->drv);
\Phake::when($this->drv)->userRemove->thenThrow(new ExceptionConflict("doesNotExist"));
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
$this->drv->userRemove->throws(new ExceptionConflict("doesNotExist"));
$this->dbMock->userExists->returns(false);
$u = $this->prepTest();
$this->assertException("doesNotExist", "User", "ExceptionConflict");
try {
$u->remove($user);
} finally {
\Phake::verify(Arsse::$db)->userExists($user);
\Phake::verify($this->drv)->userRemove($user);
$this->dbMock->userExists->calledWith($user);
$this->drv->userRemove->calledWith($user);
}
}
public function testSetAPassword(): void {
$user = "john.doe@example.com";
$pass = "secret";
$u = new User($this->drv);
\Phake::when($this->drv)->userPasswordSet->thenReturn($pass);
\Phake::when(Arsse::$db)->userPasswordSet->thenReturn($pass);
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
$this->drv->userPasswordSet->returns($pass);
$this->dbMock->userPasswordSet->returns($pass);
$this->dbMock->userExists->returns(true);
$u = $this->prepTest();
$this->assertSame($pass, $u->passwordSet($user, $pass));
\Phake::verify($this->drv)->userPasswordSet($user, $pass, null);
\Phake::verify(Arsse::$db)->userPasswordSet($user, $pass, null);
\Phake::verify(Arsse::$db)->sessionDestroy($user);
\Phake::verify(Arsse::$db)->userExists($user);
$this->drv->userPasswordSet->calledWith($user, $pass, null);
$this->dbMock->userPasswordSet->calledWith($user, $pass);
$this->dbMock->sessionDestroy->calledWith($user);
$this->dbMock->userExists->calledWith($user);
}
public function testSetARandomPassword(): void {
$user = "john.doe@example.com";
$pass = "random password";
$u = \Phake::partialMock(User::class, $this->drv);
\Phake::when($u)->generatePassword->thenReturn($pass);
\Phake::when($this->drv)->userPasswordSet->thenReturn(null)->thenReturn($pass);
\Phake::when(Arsse::$db)->userPasswordSet->thenReturn($pass);
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
$this->drv->userPasswordSet->returns(null)->returns($pass);
$this->dbMock->userPasswordSet->returns($pass);
$this->dbMock->userExists->returns(true);
$u = $this->prepTest(function ($u) use ($pass) {
$u->generatePassword->returns($pass);
});
$this->assertSame($pass, $u->passwordSet($user, null));
\Phake::verify($this->drv)->userPasswordSet($user, null, null);
\Phake::verify($this->drv)->userPasswordSet($user, $pass, null);
\Phake::verify(Arsse::$db)->userPasswordSet($user, $pass, null);
\Phake::verify(Arsse::$db)->sessionDestroy($user);
\Phake::verify(Arsse::$db)->userExists($user);
$this->drv->userPasswordSet->calledWith($user, null, null);
$this->drv->userPasswordSet->calledWith($user, $pass, null);
$this->dbMock->userPasswordSet->calledWith($user, $pass);
$this->dbMock->sessionDestroy->calledWith($user);
$this->dbMock->userExists->calledWith($user);
}
public function testSetAPasswordForAUserWeDoNotKnow(): void {
$user = "john.doe@example.com";
$pass = "secret";
$u = new User($this->drv);
\Phake::when($this->drv)->userPasswordSet->thenReturn($pass);
\Phake::when(Arsse::$db)->userPasswordSet->thenReturn($pass);
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
$this->drv->userPasswordSet->returns($pass);
$this->dbMock->userPasswordSet->returns($pass);
$this->dbMock->userExists->returns(false);
$u = $this->prepTest();
$this->assertSame($pass, $u->passwordSet($user, $pass));
\Phake::verify($this->drv)->userPasswordSet($user, $pass, null);
\Phake::verify(Arsse::$db)->userAdd($user, $pass);
\Phake::verify(Arsse::$db)->userExists($user);
$this->drv->userPasswordSet->calledWith($user, $pass, null);
$this->dbMock->userAdd->calledWith($user, $pass);
$this->dbMock->userExists->calledWith($user);
}
public function testSetARandomPasswordForAUserWeDoNotKnow(): void {
$user = "john.doe@example.com";
$pass = "random password";
$u = \Phake::partialMock(User::class, $this->drv);
\Phake::when($u)->generatePassword->thenReturn($pass);
\Phake::when($this->drv)->userPasswordSet->thenReturn(null)->thenReturn($pass);
\Phake::when(Arsse::$db)->userPasswordSet->thenReturn($pass);
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
$this->drv->userPasswordSet->returns(null)->returns($pass);
$this->dbMock->userPasswordSet->returns($pass);
$this->dbMock->userExists->returns(false);
$u = $this->prepTest(function ($u) use ($pass) {
$u->generatePassword->returns($pass);
});
$this->assertSame($pass, $u->passwordSet($user, null));
\Phake::verify($this->drv)->userPasswordSet($user, null, null);
\Phake::verify($this->drv)->userPasswordSet($user, $pass, null);
\Phake::verify(Arsse::$db)->userAdd($user, $pass);
\Phake::verify(Arsse::$db)->userExists($user);
$this->drv->userPasswordSet->calledWith($user, null, null);
$this->drv->userPasswordSet->calledWith($user, $pass, null);
$this->dbMock->userAdd->calledWith($user, $pass);
$this->dbMock->userExists->calledWith($user);
}
public function testSetARandomPasswordForAMissingUser(): void {
$user = "john.doe@example.com";
$pass = "random password";
$u = \Phake::partialMock(User::class, $this->drv);
\Phake::when($u)->generatePassword->thenReturn($pass);
\Phake::when($this->drv)->userPasswordSet->thenThrow(new ExceptionConflict("doesNotExist"));
$this->drv->userPasswordSet->throws(new ExceptionConflict("doesNotExist"));
$u = $this->prepTest(function ($u) use ($pass) {
$u->generatePassword->returns($pass);
});
$this->assertException("doesNotExist", "User", "ExceptionConflict");
try {
$u->passwordSet($user, null);
} finally {
\Phake::verify($this->drv)->userPasswordSet($user, null, null);
$this->drv->userPasswordSet->calledWith($user, null, null);
}
}
public function testUnsetAPassword(): void {
$user = "john.doe@example.com";
$u = new User($this->drv);
\Phake::when($this->drv)->userPasswordUnset->thenReturn(true);
\Phake::when(Arsse::$db)->userPasswordUnset->thenReturn(true);
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
$this->drv->userPasswordUnset->returns(true);
$this->dbMock->userPasswordSet->returns(true);
$this->dbMock->userExists->returns(true);
$u = $this->prepTest();
$this->assertTrue($u->passwordUnset($user));
\Phake::verify($this->drv)->userPasswordUnset($user, null);
\Phake::verify(Arsse::$db)->userPasswordSet($user, null);
\Phake::verify(Arsse::$db)->sessionDestroy($user);
\Phake::verify(Arsse::$db)->userExists($user);
$this->drv->userPasswordUnset->calledWith($user, null);
$this->dbMock->userPasswordSet->calledWith($user, null);
$this->dbMock->sessionDestroy->calledWith($user);
$this->dbMock->userExists->calledWith($user);
}
public function testUnsetAPasswordForAUserWeDoNotKnow(): void {
$user = "john.doe@example.com";
$u = new User($this->drv);
\Phake::when($this->drv)->userPasswordUnset->thenReturn(true);
\Phake::when(Arsse::$db)->userPasswordUnset->thenReturn(true);
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
$this->drv->userPasswordUnset->returns(true);
$this->dbMock->userPasswordSet->returns(true);
$this->dbMock->userExists->returns(false);
$u = $this->prepTest();
$this->assertTrue($u->passwordUnset($user));
\Phake::verify($this->drv)->userPasswordUnset($user, null);
\Phake::verify(Arsse::$db)->userExists($user);
$this->drv->userPasswordUnset->calledWith($user, null);
$this->dbMock->userExists->calledWith($user);
}
public function testUnsetAPasswordForAMissingUser(): void {
$user = "john.doe@example.com";
$u = new User($this->drv);
\Phake::when($this->drv)->userPasswordUnset->thenThrow(new ExceptionConflict("doesNotExist"));
$this->drv->userPasswordUnset->throws(new ExceptionConflict("doesNotExist"));
$u = $this->prepTest();
$this->assertException("doesNotExist", "User", "ExceptionConflict");
try {
$u->passwordUnset($user);
} finally {
\Phake::verify($this->drv)->userPasswordUnset($user, null);
$this->drv->userPasswordUnset->calledWith($user, null);
}
}
@ -415,14 +425,14 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
public function testGetThePropertiesOfAUser(array $exp, array $base, array $extra): void {
$user = "john.doe@example.com";
$exp = array_merge(['num' => null], array_combine(array_keys(User::PROPERTIES), array_fill(0, sizeof(User::PROPERTIES), null)), $exp);
$u = new User($this->drv);
\Phake::when($this->drv)->userPropertiesGet->thenReturn($extra);
\Phake::when(Arsse::$db)->userPropertiesGet->thenReturn($base);
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
$this->drv->userPropertiesGet->returns($extra);
$this->dbMock->userPropertiesGet->returns($base);
$this->dbMock->userExists->returns(true);
$u = $this->prepTest();
$this->assertSame($exp, $u->propertiesGet($user));
\Phake::verify($this->drv)->userPropertiesGet($user, true);
\Phake::verify(Arsse::$db)->userPropertiesGet($user, true);
\Phake::verify(Arsse::$db)->userExists($user);
$this->drv->userPropertiesGet->calledWith($user, true);
$this->dbMock->userPropertiesGet->calledWith($user, true);
$this->dbMock->userExists->calledWith($user);
}
public function provideProperties(): iterable {
@ -441,65 +451,67 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
$base = ['num' => 47, 'admin' => false, 'lang' => null, 'tz' => "Etc/UTC", 'sort_asc' => false];
$exp = ['num' => 47, 'admin' => false, 'lang' => null, 'tz' => "Europe/Istanbul", 'sort_asc' => false];
$exp = array_merge(['num' => null], array_combine(array_keys(User::PROPERTIES), array_fill(0, sizeof(User::PROPERTIES), null)), $exp);
$u = new User($this->drv);
\Phake::when($this->drv)->userPropertiesGet->thenReturn($extra);
\Phake::when(Arsse::$db)->userPropertiesGet->thenReturn($base);
\Phake::when(Arsse::$db)->userAdd->thenReturn(true);
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
$this->drv->userPropertiesGet->returns($extra);
$this->dbMock->userPropertiesGet->returns($base);
$this->dbMock->userAdd->returns(true);
$this->dbMock->userExists->returns(false);
$u = $this->prepTest();
$this->assertSame($exp, $u->propertiesGet($user));
\Phake::verify($this->drv)->userPropertiesGet($user, true);
\Phake::verify(Arsse::$db)->userPropertiesGet($user, true);
\Phake::verify(Arsse::$db)->userPropertiesSet($user, $extra);
\Phake::verify(Arsse::$db)->userAdd($user, null);
\Phake::verify(Arsse::$db)->userExists($user);
$this->drv->userPropertiesGet->calledWith($user, true);
$this->dbMock->userPropertiesGet->calledWith($user, true);
$this->dbMock->userPropertiesSet->calledWith($user, $extra);
$this->dbMock->userAdd->calledWith($user, null);
$this->dbMock->userExists->calledWith($user);
}
public function testGetThePropertiesOfAMissingUser(): void {
$user = "john.doe@example.com";
$u = new User($this->drv);
\Phake::when($this->drv)->userPropertiesGet->thenThrow(new ExceptionConflict("doesNotExist"));
$this->drv->userPropertiesGet->throws(new ExceptionConflict("doesNotExist"));
$u = $this->prepTest();
$this->assertException("doesNotExist", "User", "ExceptionConflict");
try {
$u->propertiesGet($user);
} finally {
\Phake::verify($this->drv)->userPropertiesGet($user, true);
$this->drv->userPropertiesGet->calledWith($user, true);
}
}
/** @dataProvider providePropertyChanges */
public function testSetThePropertiesOfAUser(array $in, $out): void {
$user = "john.doe@example.com";
$u = new User($this->drv);
if ($out instanceof \Exception) {
$u = $this->prepTest();
$this->assertException($out);
$u->propertiesSet($user, $in);
} else {
\Phake::when(Arsse::$db)->userExists->thenReturn(true);
\Phake::when($this->drv)->userPropertiesSet->thenReturn($out);
\Phake::when(Arsse::$db)->userPropertiesSet->thenReturn(true);
$this->dbMock->userExists->returns(true);
$this->drv->userPropertiesSet->returns($out);
$this->dbMock->userPropertiesSet->returns(true);
$u = $this->prepTest();
$this->assertSame($out, $u->propertiesSet($user, $in));
\Phake::verify($this->drv)->userPropertiesSet($user, $in);
\Phake::verify(Arsse::$db)->userPropertiesSet($user, $out);
\Phake::verify(Arsse::$db)->userExists($user);
$this->drv->userPropertiesSet->calledWith($user, $in);
$this->dbMock->userPropertiesSet->calledWith($user, $out);
$this->dbMock->userExists->calledWith($user);
}
}
/** @dataProvider providePropertyChanges */
public function testSetThePropertiesOfAUserWeDoNotKnow(array $in, $out): void {
$user = "john.doe@example.com";
$u = new User($this->drv);
if ($out instanceof \Exception) {
$u = $this->prepTest();
$this->assertException($out);
$u->propertiesSet($user, $in);
} else {
\Phake::when(Arsse::$db)->userExists->thenReturn(false);
\Phake::when($this->drv)->userPropertiesSet->thenReturn($out);
\Phake::when(Arsse::$db)->userPropertiesSet->thenReturn(true);
$this->dbMock->userExists->returns(false);
$this->drv->userPropertiesSet->returns($out);
$this->dbMock->userPropertiesSet->returns(true);
$u = $this->prepTest();
$this->assertSame($out, $u->propertiesSet($user, $in));
\Phake::verify($this->drv)->userPropertiesSet($user, $in);
\Phake::verify(Arsse::$db)->userPropertiesSet($user, $out);
\Phake::verify(Arsse::$db)->userExists($user);
\Phake::verify(Arsse::$db)->userAdd($user, null);
$this->drv->userPropertiesSet->calledWith($user, $in);
$this->dbMock->userPropertiesSet->calledWith($user, $out);
$this->dbMock->userExists->calledWith($user);
$this->dbMock->userAdd->calledWith($user, null);
}
}
@ -520,13 +532,13 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
public function testSetThePropertiesOfAMissingUser(): void {
$user = "john.doe@example.com";
$in = ['admin' => true];
$u = new User($this->drv);
\Phake::when($this->drv)->userPropertiesSet->thenThrow(new ExceptionConflict("doesNotExist"));
$this->drv->userPropertiesSet->throws(new ExceptionConflict("doesNotExist"));
$u = $this->prepTest();
$this->assertException("doesNotExist", "User", "ExceptionConflict");
try {
$u->propertiesSet($user, $in);
} finally {
\Phake::verify($this->drv)->userPropertiesSet($user, $in);
$this->drv->userPropertiesSet->calledWith($user, $in);
}
}
}

View file

@ -37,14 +37,16 @@ trait Setup {
// set up a file without read access
chmod($this->path."ru.php", 0000);
// make the test Lang class use the vfs files
$this->l = \Phake::partialMock(Lang::class, $this->path);
\Phake::when($this->l)->globFiles->thenReturnCallback(function(string $path): array {
$this->l = $this->partialMock(Lang::class, $this->path);
$this->l->globFiles->does(function(string $path): array {
return Glob::glob($this->path."*.php");
});
$this->l = $this->l->get();
// create a mock Lang object so as not to create a dependency loop
self::clearData(false);
Arsse::$lang = \Phake::mock(Lang::class);
\Phake::when(Arsse::$lang)->msg->thenReturn("");
Arsse::$lang = $this->mock(Lang::class);
Arsse::$lang->msg->returns("");
Arsse::$lang = Arsse::$lang->get();
// call the additional setup method if it exists
if (method_exists($this, "setUpSeries")) {
$this->setUpSeries();
@ -52,9 +54,6 @@ trait Setup {
}
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);
// call the additional teardiwn method if it exists

View file

@ -2,7 +2,6 @@
"require-dev": {
"phpunit/phpunit": "^8.0 || ^9.0",
"dms/phpunit-arraysubset-asserts": "^0.1 || ^0.2",
"phake/phake": "^3.0",
"clue/arguments": "^2.0",
"mikey179/vfsstream": "^1.6",
"webmozart/glob": "^4.1",

View file

@ -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": "fda9bd2446005dfe56a223890cad0849",
"content-hash": "ee93856e05f6ce1cc763b474c94dad6c",
"packages": [],
"packages-dev": [
{
@ -500,68 +500,6 @@
},
"time": "2020-12-20T10:01:03+00:00"
},
{
"name": "phake/phake",
"version": "v3.1.8",
"source": {
"type": "git",
"url": "https://github.com/mlively/Phake.git",
"reference": "9f9dfb12c9ce6e38c73de9631ea2ab0f0ea36a65"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mlively/Phake/zipball/9f9dfb12c9ce6e38c73de9631ea2ab0f0ea36a65",
"reference": "9f9dfb12c9ce6e38c73de9631ea2ab0f0ea36a65",
"shasum": ""
},
"require": {
"php": ">=7",
"sebastian/comparator": "^1.1|^2.0|^3.0|^4.0"
},
"require-dev": {
"codeclimate/php-test-reporter": "dev-master",
"doctrine/common": "2.3.*",
"ext-soap": "*",
"hamcrest/hamcrest-php": "1.1.*",
"phpunit/phpunit": "^7.0"
},
"suggest": {
"doctrine/common": "Allows mock annotations to use import statements for classes.",
"hamcrest/hamcrest-php": "Use Hamcrest matchers."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0.0-dev"
}
},
"autoload": {
"psr-0": {
"Phake": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Mike Lively",
"email": "m@digitalsandwich.com"
}
],
"description": "The Phake mock testing library",
"homepage": "https://github.com/mlively/Phake",
"keywords": [
"mock",
"testing"
],
"support": {
"issues": "https://github.com/mlively/Phake/issues",
"source": "https://github.com/mlively/Phake/tree/v3.1.8"
},
"time": "2020-05-11T18:43:26+00:00"
},
{
"name": "phar-io/manifest",
"version": "2.0.1",