1
1
Fork 0
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:
J. King 2020-11-17 16:23:36 -05:00
parent e16df90bae
commit d3ebb1bd56
3 changed files with 114 additions and 10 deletions

View file

@ -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;

View file

@ -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',

View file

@ -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);
}
}
} }