mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 21:22:40 +00:00
Last set of tests for user management. Fixes #180
This commit is contained in:
parent
e16df90bae
commit
d3ebb1bd56
3 changed files with 114 additions and 10 deletions
11
lib/User.php
11
lib/User.php
|
@ -70,6 +70,7 @@ class User {
|
||||||
return $out;
|
return $out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function remove(string $user): bool {
|
public function remove(string $user): bool {
|
||||||
try {
|
try {
|
||||||
$out = $this->u->userRemove($user);
|
$out = $this->u->userRemove($user);
|
||||||
|
@ -141,15 +142,15 @@ class User {
|
||||||
$in = [];
|
$in = [];
|
||||||
if (array_key_exists("tz", $data)) {
|
if (array_key_exists("tz", $data)) {
|
||||||
if (!is_string($data['tz'])) {
|
if (!is_string($data['tz'])) {
|
||||||
throw new User\ExceptionInput("invalidTimezone");
|
throw new User\ExceptionInput("invalidTimezone", ['field' => "tz", 'value' => ""]);
|
||||||
} elseif (!in_array($data['tz'], \DateTimeZone::listIdentifiers())) {
|
} elseif(!@timezone_open($data['tz'])) {
|
||||||
throw new User\ExceptionInput("invalidTimezone", $data['tz']);
|
throw new User\ExceptionInput("invalidTimezone", ['field' => "tz", 'value' => $data['tz']]);
|
||||||
}
|
}
|
||||||
$in['tz'] = $data['tz'];
|
$in['tz'] = $data['tz'];
|
||||||
}
|
}
|
||||||
foreach (["admin", "sort_asc"] as $k) {
|
foreach (["admin", "sort_asc"] as $k) {
|
||||||
if (array_key_exists($k, $data)) {
|
if (array_key_exists($k, $data)) {
|
||||||
if (($v = V::normalize($data[$k], V::T_BOOL)) === null) {
|
if (($v = V::normalize($data[$k], V::T_BOOL | V::M_DROP)) === null) {
|
||||||
throw new User\ExceptionInput("invalidBoolean", $k);
|
throw new User\ExceptionInput("invalidBoolean", $k);
|
||||||
}
|
}
|
||||||
$in[$k] = $v;
|
$in[$k] = $v;
|
||||||
|
@ -161,7 +162,7 @@ class User {
|
||||||
$out = $this->u->userPropertiesSet($user, $in);
|
$out = $this->u->userPropertiesSet($user, $in);
|
||||||
// synchronize the internal database
|
// synchronize the internal database
|
||||||
if (!Arsse::$db->userExists($user)) {
|
if (!Arsse::$db->userExists($user)) {
|
||||||
Arsse::$db->userAdd($user, $this->generatePassword());
|
Arsse::$db->userAdd($user, null);
|
||||||
}
|
}
|
||||||
Arsse::$db->userPropertiesSet($user, $out);
|
Arsse::$db->userPropertiesSet($user, $out);
|
||||||
return $out;
|
return $out;
|
||||||
|
|
|
@ -140,6 +140,8 @@ return [
|
||||||
'Exception.JKingWeb/Arsse/User/Exception.authFailed' => 'Authentication failed',
|
'Exception.JKingWeb/Arsse/User/Exception.authFailed' => 'Authentication failed',
|
||||||
'Exception.JKingWeb/Arsse/User/ExceptionSession.invalid' => 'Session with ID {0} does not exist',
|
'Exception.JKingWeb/Arsse/User/ExceptionSession.invalid' => 'Session with ID {0} does not exist',
|
||||||
'Exception.JKingWeb/Arsse/User/ExceptionInput.invalidUsername' => 'User names may not contain the Unicode character {0}',
|
'Exception.JKingWeb/Arsse/User/ExceptionInput.invalidUsername' => 'User names may not contain the Unicode character {0}',
|
||||||
|
'Exception.JKingWeb/Arsse/User/ExceptionInput.invalidBoolean' => 'User property "{0}" must be a boolean value (true or false)',
|
||||||
|
'Exception.JKingWeb/Arsse/User/ExceptionInput.invalidTimezone' => 'User property "{field}" must be a valid zoneinfo timezone',
|
||||||
'Exception.JKingWeb/Arsse/Feed/Exception.internalError' => 'Could not download feed "{url}" because of an internal error which is probably a bug',
|
'Exception.JKingWeb/Arsse/Feed/Exception.internalError' => 'Could not download feed "{url}" because of an internal error which is probably a bug',
|
||||||
'Exception.JKingWeb/Arsse/Feed/Exception.invalidCertificate' => 'Could not download feed "{url}" because its server is serving an invalid SSL certificate',
|
'Exception.JKingWeb/Arsse/Feed/Exception.invalidCertificate' => 'Could not download feed "{url}" because its server is serving an invalid SSL certificate',
|
||||||
'Exception.JKingWeb/Arsse/Feed/Exception.invalidUrl' => 'Feed URL "{url}" is invalid',
|
'Exception.JKingWeb/Arsse/Feed/Exception.invalidUrl' => 'Feed URL "{url}" is invalid',
|
||||||
|
|
|
@ -9,6 +9,7 @@ namespace JKingWeb\Arsse\TestCase\User;
|
||||||
use JKingWeb\Arsse\Arsse;
|
use JKingWeb\Arsse\Arsse;
|
||||||
use JKingWeb\Arsse\Database;
|
use JKingWeb\Arsse\Database;
|
||||||
use JKingWeb\Arsse\User;
|
use JKingWeb\Arsse\User;
|
||||||
|
use JKingWeb\Arsse\AbstractException as Exception;
|
||||||
use JKingWeb\Arsse\User\ExceptionConflict;
|
use JKingWeb\Arsse\User\ExceptionConflict;
|
||||||
use JKingWeb\Arsse\User\ExceptionInput;
|
use JKingWeb\Arsse\User\ExceptionInput;
|
||||||
use JKingWeb\Arsse\User\Driver;
|
use JKingWeb\Arsse\User\Driver;
|
||||||
|
@ -43,6 +44,13 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
$this->assertSame("", (string) $u);
|
$this->assertSame("", (string) $u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGeneratePasswords(): void {
|
||||||
|
$u = new User($this->drv);
|
||||||
|
$pass1 = $u->generatePassword();
|
||||||
|
$pass2 = $u->generatePassword();
|
||||||
|
$this->assertNotEquals($pass1, $pass2);
|
||||||
|
}
|
||||||
|
|
||||||
/** @dataProvider provideAuthentication */
|
/** @dataProvider provideAuthentication */
|
||||||
public function testAuthenticateAUser(bool $preAuth, string $user, string $password, bool $exp): void {
|
public function testAuthenticateAUser(bool $preAuth, string $user, string $password, bool $exp): void {
|
||||||
Arsse::$conf->userPreAuth = $preAuth;
|
Arsse::$conf->userPreAuth = $preAuth;
|
||||||
|
@ -343,4 +351,97 @@ class TestUser extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||||
[['num' => 1, 'admin' => true, 'lang' => null, 'tz' => "America/Toronto", 'sort_asc' => true], ['num' => 1, 'admin' => true, 'lang' => "fr", 'tz' => "America/Toronto", 'sort_asc' => true], ['lang' => null]],
|
[['num' => 1, 'admin' => true, 'lang' => null, 'tz' => "America/Toronto", 'sort_asc' => true], ['num' => 1, 'admin' => true, 'lang' => "fr", 'tz' => "America/Toronto", 'sort_asc' => true], ['lang' => null]],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetThePropertiesOfAUserWeDoNotKnow(): void {
|
||||||
|
$user = "john.doe@example.com";
|
||||||
|
$extra = ['tz' => "Europe/Istanbul"];
|
||||||
|
$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];
|
||||||
|
$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->assertSame($exp, $u->propertiesGet($user));
|
||||||
|
\Phake::verify($this->drv)->userPropertiesGet($user);
|
||||||
|
\Phake::verify(Arsse::$db)->userPropertiesGet($user);
|
||||||
|
\Phake::verify(Arsse::$db)->userPropertiesSet($user, $extra);
|
||||||
|
\Phake::verify(Arsse::$db)->userAdd($user, null);
|
||||||
|
\Phake::verify(Arsse::$db)->userExists($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->assertException("doesNotExist", "User", "ExceptionConflict");
|
||||||
|
try {
|
||||||
|
$u->propertiesGet($user);
|
||||||
|
} finally {
|
||||||
|
\Phake::verify($this->drv)->userPropertiesGet($user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @dataProvider providePropertyChanges */
|
||||||
|
public function testSetThePropertiesOfAUser(array $in, $out): void {
|
||||||
|
$user = "john.doe@example.com";
|
||||||
|
$u = new User($this->drv);
|
||||||
|
if ($out instanceof \Exception) {
|
||||||
|
$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->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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @dataProvider providePropertyChanges */
|
||||||
|
public function testSetThePropertiesOfAUserWeDoNotKnow(array $in, $out): void {
|
||||||
|
$user = "john.doe@example.com";
|
||||||
|
$u = new User($this->drv);
|
||||||
|
if ($out instanceof \Exception) {
|
||||||
|
$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->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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function providePropertyChanges(): iterable {
|
||||||
|
return [
|
||||||
|
[['admin' => true], ['admin' => true]],
|
||||||
|
[['admin' => 2], new ExceptionInput("invalidBoolean")],
|
||||||
|
[['sort_asc' => 2], new ExceptionInput("invalidBoolean")],
|
||||||
|
[['tz' => "Etc/UTC"], ['tz' => "Etc/UTC"]],
|
||||||
|
[['tz' => "Etc/blah"], new ExceptionInput("invalidTimezone")],
|
||||||
|
[['tz' => false], new ExceptionInput("invalidTimezone")],
|
||||||
|
[['lang' => "en-ca"], ['lang' => "en-CA"]],
|
||||||
|
[['lang' => null], ['lang' => null]],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
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->assertException("doesNotExist", "User", "ExceptionConflict");
|
||||||
|
try {
|
||||||
|
$u->propertiesSet($user, $in);
|
||||||
|
} finally {
|
||||||
|
\Phake::verify($this->drv)->userPropertiesSet($user, $in);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue