mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 21:22:40 +00:00
Full set of tests for user-related Database funcs
- Fixed a few inconsistencies and bugs along the way - User manager tests need some equivalent fleshing out
This commit is contained in:
parent
9338219a68
commit
dbd735f1f3
5 changed files with 351 additions and 32 deletions
|
@ -18,7 +18,11 @@ class Database {
|
||||||
return (string) preg_filter("[^0-9a-zA-Z_\.]", "", $name);
|
return (string) preg_filter("[^0-9a-zA-Z_\.]", "", $name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct(Db\Driver $db = null) {
|
||||||
|
// if we're fed a pre-prepared driver, use it'
|
||||||
|
if($db) {
|
||||||
|
$this->db = $db;
|
||||||
|
} else {
|
||||||
$this->driver = $driver = Data::$conf->dbDriver;
|
$this->driver = $driver = Data::$conf->dbDriver;
|
||||||
$this->db = new $driver(INSTALL);
|
$this->db = new $driver(INSTALL);
|
||||||
$ver = $this->db->schemaVersion();
|
$ver = $this->db->schemaVersion();
|
||||||
|
@ -26,6 +30,7 @@ class Database {
|
||||||
$this->db->schemaUpdate(self::SCHEMA_VERSION);
|
$this->db->schemaUpdate(self::SCHEMA_VERSION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static public function listDrivers(): array {
|
static public function listDrivers(): array {
|
||||||
$sep = \DIRECTORY_SEPARATOR;
|
$sep = \DIRECTORY_SEPARATOR;
|
||||||
|
@ -186,16 +191,22 @@ class Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function userList(string $domain = null): array {
|
public function userList(string $domain = null): array {
|
||||||
|
$out = [];
|
||||||
if($domain !== null) {
|
if($domain !== null) {
|
||||||
if(!Data::$user->authorize("@".$domain, __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $domain]);
|
if(!Data::$user->authorize("@".$domain, __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $domain]);
|
||||||
$domain = str_replace(["\\","%","_"],["\\\\", "\\%", "\\_"], $domain);
|
$domain = str_replace(["\\","%","_"],["\\\\", "\\%", "\\_"], $domain);
|
||||||
$domain = "%@".$domain;
|
$domain = "%@".$domain;
|
||||||
return $this->db->prepare("SELECT id from arsse_users where id like ?", "str")->run($domain)->getAll();
|
foreach($this->db->prepare("SELECT id from arsse_users where id like ?", "str")->run($domain) as $user) {
|
||||||
|
$out[] = $user['id'];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if(!Data::$user->authorize("", __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => "global"]);
|
if(!Data::$user->authorize("", __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => "global"]);
|
||||||
return $this->db->prepare("SELECT id from arsse_users")->run()->getAll();
|
foreach($this->db->prepare("SELECT id from arsse_users")->run() as $user) {
|
||||||
|
$out[] = $user['id'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
public function userPasswordGet(string $user): string {
|
public function userPasswordGet(string $user): string {
|
||||||
if(!Data::$user->authorize($user, __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
|
if(!Data::$user->authorize($user, __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
|
||||||
|
@ -208,7 +219,7 @@ class Database {
|
||||||
if(!$this->userExists($user)) throw new User\Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]);
|
if(!$this->userExists($user)) throw new User\Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]);
|
||||||
if($password===null) $password = (new PassGen)->length(Data::$conf->userTempPasswordLength)->get();
|
if($password===null) $password = (new PassGen)->length(Data::$conf->userTempPasswordLength)->get();
|
||||||
$hash = "";
|
$hash = "";
|
||||||
if(strlen($password > 0)) $hash = password_hash($password, \PASSWORD_DEFAULT);
|
if(strlen($password) > 0) $hash = password_hash($password, \PASSWORD_DEFAULT);
|
||||||
$this->db->prepare("UPDATE arsse_users set password = ? where id is ?", "str", "str")->run($hash, $user);
|
$this->db->prepare("UPDATE arsse_users set password = ? where id is ?", "str", "str")->run($hash, $user);
|
||||||
return $password;
|
return $password;
|
||||||
}
|
}
|
||||||
|
@ -216,16 +227,16 @@ class Database {
|
||||||
public function userPropertiesGet(string $user): array {
|
public function userPropertiesGet(string $user): array {
|
||||||
if(!Data::$user->authorize($user, __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
|
if(!Data::$user->authorize($user, __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
|
||||||
$prop = $this->db->prepare("SELECT name,rights from arsse_users where id is ?", "str")->run($user)->getRow();
|
$prop = $this->db->prepare("SELECT name,rights from arsse_users where id is ?", "str")->run($user)->getRow();
|
||||||
if(!$prop) return [];
|
if(!$prop) throw new User\Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]);
|
||||||
return $prop;
|
return $prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function userPropertiesSet(string $user, array &$properties): array {
|
public function userPropertiesSet(string $user, array $properties): array {
|
||||||
if(!Data::$user->authorize($user, __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
|
if(!Data::$user->authorize($user, __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
|
||||||
$valid = [ // FIXME: add future properties
|
$valid = [ // FIXME: add future properties
|
||||||
"name" => "str",
|
"name" => "str",
|
||||||
];
|
];
|
||||||
if(!$this->userExists($user)) return [];
|
if(!$this->userExists($user)) throw new User\Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]);
|
||||||
$this->db->begin();
|
$this->db->begin();
|
||||||
foreach($valid as $prop => $type) {
|
foreach($valid as $prop => $type) {
|
||||||
if(!array_key_exists($prop, $properties)) continue;
|
if(!array_key_exists($prop, $properties)) continue;
|
||||||
|
@ -242,7 +253,7 @@ class Database {
|
||||||
|
|
||||||
public function userRightsSet(string $user, int $rights): bool {
|
public function userRightsSet(string $user, int $rights): bool {
|
||||||
if(!Data::$user->authorize($user, __FUNCTION__, $rights)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
|
if(!Data::$user->authorize($user, __FUNCTION__, $rights)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
|
||||||
if(!$this->userExists($user)) return false;
|
if(!$this->userExists($user)) throw new User\Exception("doesNotExist", ["action" => __FUNCTION__, "user" => $user]);
|
||||||
$this->db->prepare("UPDATE arsse_users set rights = ? where id is ?", "int", "str")->run($rights, $user);
|
$this->db->prepare("UPDATE arsse_users set rights = ? where id is ?", "int", "str")->run($rights, $user);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
289
tests/Db/SQLite3/Database/TestDatabaseUser.php
Normal file
289
tests/Db/SQLite3/Database/TestDatabaseUser.php
Normal file
|
@ -0,0 +1,289 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
namespace JKingWeb\Arsse;
|
||||||
|
use Phake;
|
||||||
|
|
||||||
|
|
||||||
|
class TestDatabaseUser extends \PHPUnit\Framework\TestCase {
|
||||||
|
use Test\Tools, Test\Db\Tools;
|
||||||
|
|
||||||
|
protected $drv;
|
||||||
|
protected $data = [
|
||||||
|
'arsse_users' => [
|
||||||
|
'columns' => [
|
||||||
|
'id' => 'str',
|
||||||
|
'password' => 'str',
|
||||||
|
'name' => 'str',
|
||||||
|
'rights' => 'int',
|
||||||
|
],
|
||||||
|
'rows' => [
|
||||||
|
["admin@example.net", '$2y$10$PbcG2ZR3Z8TuPzM7aHTF8.v61dtCjzjK78gdZJcp4UePE8T9jEgBW', "Hard Lip Herbert", User\Driver::RIGHTS_GLOBAL_ADMIN], // password is hash of "secret"
|
||||||
|
["jane.doe@example.com", "", "Jane Doe", User\Driver::RIGHTS_NONE],
|
||||||
|
["john.doe@example.com", "", "John Doe", User\Driver::RIGHTS_NONE],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
function setUp() {
|
||||||
|
// establish a clean baseline
|
||||||
|
$this->clearData();
|
||||||
|
// create a default configuration
|
||||||
|
Data::$conf = new Conf();
|
||||||
|
// configure and create the relevant database driver
|
||||||
|
Data::$conf->dbSQLite3File = ":memory:";
|
||||||
|
$this->drv = new Db\SQLite3\Driver(true);
|
||||||
|
// create the database interface with the suitable driver
|
||||||
|
Data::$db = new Database($this->drv);
|
||||||
|
Data::$db->schemaUpdate();
|
||||||
|
// create a mock user manager
|
||||||
|
Data::$user = Phake::mock(User::class);
|
||||||
|
Phake::when(Data::$user)->authorize->thenReturn(true);
|
||||||
|
// call the additional setup method if it exists
|
||||||
|
if(method_exists($this, "setUpSeries")) $this->setUpSeries();
|
||||||
|
}
|
||||||
|
|
||||||
|
function tearDown() {
|
||||||
|
// call the additional teardiwn method if it exists
|
||||||
|
if(method_exists($this, "tearDownSeries")) $this->tearDownSeries();
|
||||||
|
// clean up
|
||||||
|
$this->drv = null;
|
||||||
|
$this->clearData();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setUpSeries() {
|
||||||
|
$this->primeDatabase($this->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCheckThatAUserExists() {
|
||||||
|
$this->assertTrue(Data::$db->userExists("jane.doe@example.com"));
|
||||||
|
$this->assertFalse(Data::$db->userExists("jane.doe@example.org"));
|
||||||
|
Phake::verify(Data::$user)->authorize("jane.doe@example.com", "userExists");
|
||||||
|
Phake::verify(Data::$user)->authorize("jane.doe@example.org", "userExists");
|
||||||
|
$this->compareExpectations($this->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCheckThatAUserExistsWithoutAuthority() {
|
||||||
|
Phake::when(Data::$user)->authorize->thenReturn(false);
|
||||||
|
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||||
|
Data::$db->userExists("jane.doe@example.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetAPassword() {
|
||||||
|
$hash = Data::$db->userPasswordGet("admin@example.net");
|
||||||
|
$this->assertSame('$2y$10$PbcG2ZR3Z8TuPzM7aHTF8.v61dtCjzjK78gdZJcp4UePE8T9jEgBW', $hash);
|
||||||
|
Phake::verify(Data::$user)->authorize("admin@example.net", "userPasswordGet");
|
||||||
|
$this->assertTrue(password_verify("secret", $hash));
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetAPasswordWithoutAuthority() {
|
||||||
|
Phake::when(Data::$user)->authorize->thenReturn(false);
|
||||||
|
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||||
|
Data::$db->userPasswordGet("admin@example.net");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testAddANewUser() {
|
||||||
|
$this->assertSame("", Data::$db->userAdd("john.doe@example.org", ""));
|
||||||
|
Phake::verify(Data::$user)->authorize("john.doe@example.org", "userAdd");
|
||||||
|
$state = $this->primeExpectations($this->data, ['arsse_users' => ['id','name','rights']]);
|
||||||
|
$state['arsse_users']['rows'][] = ["john.doe@example.org", null, User\Driver::RIGHTS_NONE];
|
||||||
|
$this->compareExpectations($state);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @depends testGetAPassword
|
||||||
|
* @depends testAddANewUser
|
||||||
|
*/
|
||||||
|
function testAddANewUserWithARandomPassword() {
|
||||||
|
$user1 = "john.doe@example.org";
|
||||||
|
$user2 = "john.doe@example.net";
|
||||||
|
$pass1 = Data::$db->userAdd($user1);
|
||||||
|
$pass2 = Data::$db->userAdd($user2);
|
||||||
|
$this->assertSame(Data::$conf->userTempPasswordLength, strlen($pass1));
|
||||||
|
$this->assertSame(Data::$conf->userTempPasswordLength, strlen($pass2));
|
||||||
|
$this->assertNotEquals($pass1, $pass2);
|
||||||
|
$hash1 = Data::$db->userPasswordGet($user1);
|
||||||
|
$hash2 = Data::$db->userPasswordGet($user2);
|
||||||
|
Phake::verify(Data::$user)->authorize($user1, "userAdd");
|
||||||
|
Phake::verify(Data::$user)->authorize($user2, "userAdd");
|
||||||
|
Phake::verify(Data::$user)->authorize($user1, "userPasswordGet");
|
||||||
|
Phake::verify(Data::$user)->authorize($user2, "userPasswordGet");
|
||||||
|
$this->assertTrue(password_verify($pass1, $hash1), "Failed verifying password of $user1 '$pass1' against hash '$hash1'.");
|
||||||
|
$this->assertTrue(password_verify($pass2, $hash2), "Failed verifying password of $user2 '$pass2' against hash '$hash2'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testAddAnExistingUser() {
|
||||||
|
$this->assertException("alreadyExists", "User");
|
||||||
|
Data::$db->userAdd("john.doe@example.com", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testAddANewUserWithoutAuthority() {
|
||||||
|
Phake::when(Data::$user)->authorize->thenReturn(false);
|
||||||
|
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||||
|
Data::$db->userAdd("john.doe@example.org", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRemoveAUser() {
|
||||||
|
$this->assertTrue(Data::$db->userRemove("admin@example.net"));
|
||||||
|
Phake::verify(Data::$user)->authorize("admin@example.net", "userRemove");
|
||||||
|
$state = $this->primeExpectations($this->data, ['arsse_users' => ['id']]);
|
||||||
|
array_shift($state['arsse_users']['rows']);
|
||||||
|
$this->compareExpectations($state);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRemoveAMissingUser() {
|
||||||
|
$this->assertException("doesNotExist", "User");
|
||||||
|
Data::$db->userRemove("john.doe@example.org");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRemoveAUserWithoutAuthority() {
|
||||||
|
Phake::when(Data::$user)->authorize->thenReturn(false);
|
||||||
|
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||||
|
Data::$db->userRemove("admin@example.net");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testListAllUsers() {
|
||||||
|
$users = ["admin@example.net", "jane.doe@example.com", "john.doe@example.com"];
|
||||||
|
$this->assertSame($users, Data::$db->userList());
|
||||||
|
Phake::verify(Data::$user)->authorize("", "userList");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testListUsersOnADomain() {
|
||||||
|
$users = ["jane.doe@example.com", "john.doe@example.com"];
|
||||||
|
$this->assertSame($users, Data::$db->userList("example.com"));
|
||||||
|
Phake::verify(Data::$user)->authorize("@example.com", "userList");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testListAllUsersWithoutAuthority() {
|
||||||
|
Phake::when(Data::$user)->authorize->thenReturn(false);
|
||||||
|
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||||
|
Data::$db->userList();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testListUsersOnADomainWithoutAuthority() {
|
||||||
|
Phake::when(Data::$user)->authorize->thenReturn(false);
|
||||||
|
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||||
|
Data::$db->userList("example.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @depends testGetAPassword
|
||||||
|
*/
|
||||||
|
function testSetAPassword() {
|
||||||
|
$user = "john.doe@example.com";
|
||||||
|
$this->assertEquals("", Data::$db->userPasswordGet($user));
|
||||||
|
$pass = Data::$db->userPasswordSet($user, "secret");
|
||||||
|
$hash = Data::$db->userPasswordGet($user);
|
||||||
|
$this->assertNotEquals("", $hash);
|
||||||
|
Phake::verify(Data::$user)->authorize($user, "userPasswordSet");
|
||||||
|
$this->assertTrue(password_verify($pass, $hash), "Failed verifying password of $user '$pass' against hash '$hash'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSetThePasswordOfAMissingUser() {
|
||||||
|
$this->assertException("doesNotExist", "User");
|
||||||
|
Data::$db->userPasswordSet("john.doe@example.org", "secret");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSetAPasswordWithoutAuthority() {
|
||||||
|
Phake::when(Data::$user)->authorize->thenReturn(false);
|
||||||
|
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||||
|
Data::$db->userPasswordSet("john.doe@example.com", "secret");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetUserProperties() {
|
||||||
|
$exp = [
|
||||||
|
'name' => 'Hard Lip Herbert',
|
||||||
|
'rights' => User\Driver::RIGHTS_GLOBAL_ADMIN,
|
||||||
|
];
|
||||||
|
$props = Data::$db->userPropertiesGet("admin@example.net");
|
||||||
|
Phake::verify(Data::$user)->authorize("admin@example.net", "userPropertiesGet");
|
||||||
|
$this->assertArraySubset($exp, $props);
|
||||||
|
$this->assertArrayNotHasKey("password", $props);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetThePropertiesOfAMissingUser() {
|
||||||
|
$this->assertException("doesNotExist", "User");
|
||||||
|
Data::$db->userPropertiesGet("john.doe@example.org");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetUserPropertiesWithoutAuthority() {
|
||||||
|
Phake::when(Data::$user)->authorize->thenReturn(false);
|
||||||
|
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||||
|
Data::$db->userPropertiesGet("john.doe@example.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSetUserProperties() {
|
||||||
|
$try = [
|
||||||
|
'name' => 'James Kirk', // only this should actually change
|
||||||
|
'password' => '000destruct0',
|
||||||
|
'rights' => User\Driver::RIGHTS_NONE,
|
||||||
|
'lifeform' => 'tribble',
|
||||||
|
];
|
||||||
|
$exp = [
|
||||||
|
'name' => 'James Kirk',
|
||||||
|
'rights' => User\Driver::RIGHTS_GLOBAL_ADMIN,
|
||||||
|
];
|
||||||
|
$props = Data::$db->userPropertiesSet("admin@example.net", $try);
|
||||||
|
Phake::verify(Data::$user)->authorize("admin@example.net", "userPropertiesSet");
|
||||||
|
$this->assertArraySubset($exp, $props);
|
||||||
|
$this->assertArrayNotHasKey("password", $props);
|
||||||
|
$state = $this->primeExpectations($this->data, ['arsse_users' => ['id','password','name','rights']]);
|
||||||
|
$state['arsse_users']['rows'][0][2] = "James Kirk";
|
||||||
|
$this->compareExpectations($state);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSetThePropertiesOfAMissingUser() {
|
||||||
|
$try = ['name' => 'John Doe'];
|
||||||
|
$this->assertException("doesNotExist", "User");
|
||||||
|
Data::$db->userPropertiesSet("john.doe@example.org", $try);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSetUserPropertiesWithoutAuthority() {
|
||||||
|
$try = ['name' => 'John Doe'];
|
||||||
|
Phake::when(Data::$user)->authorize->thenReturn(false);
|
||||||
|
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||||
|
Data::$db->userPropertiesSet("john.doe@example.com", $try);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetUserRights() {
|
||||||
|
$user1 = "john.doe@example.com";
|
||||||
|
$user2 = "admin@example.net";
|
||||||
|
$this->assertSame(User\Driver::RIGHTS_NONE, Data::$db->userRightsGet($user1));
|
||||||
|
$this->assertSame(User\Driver::RIGHTS_GLOBAL_ADMIN, Data::$db->userRightsGet($user2));
|
||||||
|
Phake::verify(Data::$user)->authorize($user1, "userRightsGet");
|
||||||
|
Phake::verify(Data::$user)->authorize($user2, "userRightsGet");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetTheRightsOfAMissingUser() {
|
||||||
|
$this->assertSame(User\Driver::RIGHTS_NONE, Data::$db->userRightsGet("john.doe@example.org"));
|
||||||
|
Phake::verify(Data::$user)->authorize("john.doe@example.org", "userRightsGet");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testGetUserRightsWithoutAuthority() {
|
||||||
|
Phake::when(Data::$user)->authorize->thenReturn(false);
|
||||||
|
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||||
|
Data::$db->userRightsGet("john.doe@example.com");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSetUserRights() {
|
||||||
|
$user = "john.doe@example.com";
|
||||||
|
$rights = User\Driver::RIGHTS_GLOBAL_ADMIN;
|
||||||
|
$this->assertTrue(Data::$db->userRightsSet($user, $rights));
|
||||||
|
Phake::verify(Data::$user)->authorize($user, "userRightsSet", $rights);
|
||||||
|
$state = $this->primeExpectations($this->data, ['arsse_users' => ['id','rights']]);
|
||||||
|
$state['arsse_users']['rows'][2][1] = $rights;
|
||||||
|
$this->compareExpectations($state);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSetTheRightsOfAMissingUser() {
|
||||||
|
$rights = User\Driver::RIGHTS_GLOBAL_ADMIN;
|
||||||
|
$this->assertException("doesNotExist", "User");
|
||||||
|
Data::$db->userRightsSet("john.doe@example.org", $rights);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testSetUserRightsWithoutAuthority() {
|
||||||
|
$rights = User\Driver::RIGHTS_GLOBAL_ADMIN;
|
||||||
|
Phake::when(Data::$user)->authorize->thenReturn(false);
|
||||||
|
$this->assertException("notAuthorized", "User", "ExceptionAuthz");
|
||||||
|
Data::$db->userRightsSet("john.doe@example.com", $rights);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +0,0 @@
|
||||||
<?php
|
|
||||||
declare(strict_types=1);
|
|
||||||
namespace JKingWeb\Arsse;
|
|
||||||
|
|
||||||
|
|
||||||
class TestDatabase extends \PHPUnit\Framework\TestCase {
|
|
||||||
use Test\Tools, Test\Db\Tools;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -6,8 +6,8 @@ trait Tools {
|
||||||
protected $drv;
|
protected $drv;
|
||||||
|
|
||||||
|
|
||||||
function prime(array $data): bool {
|
function primeDatabase(array $data): bool {
|
||||||
$drv->begin();
|
$this->drv->begin();
|
||||||
foreach($data as $table => $info) {
|
foreach($data as $table => $info) {
|
||||||
$cols = implode(",", array_keys($info['columns']));
|
$cols = implode(",", array_keys($info['columns']));
|
||||||
$bindings = array_values($info['columns']);
|
$bindings = array_values($info['columns']);
|
||||||
|
@ -17,21 +17,50 @@ trait Tools {
|
||||||
$this->assertEquals(1, $s->runArray($row)->changes());
|
$this->assertEquals(1, $s->runArray($row)->changes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$drv->commit();
|
$this->drv->commit();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function compare(array $expected): bool {
|
function compareExpectations(array $expected): bool {
|
||||||
foreach($expected as $table => $info) {
|
foreach($expected as $table => $info) {
|
||||||
$cols = implode(",", array_keys($info['columns']));
|
$cols = implode(",", array_keys($info['columns']));
|
||||||
foreach($this->drv->prepare("SELECT $cols from $table")->run() as $num => $row) {
|
foreach($this->drv->prepare("SELECT $cols from $table")->run() as $num => $row) {
|
||||||
$row = array_values($row);
|
$row = array_values($row);
|
||||||
$assertSame($expected[$table]['rows'][$num], $row, "Row $num of table $table does not match expectation.");
|
$this->assertSame($expected[$table]['rows'][$num], $row, "Row ".($num+1)." of table $table does not match expectations at array index $num.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setUp() {
|
function primeExpectations(array $source, array $tableSpecs = null): array {
|
||||||
|
$out = [];
|
||||||
|
foreach($tableSpecs as $table => $columns) {
|
||||||
|
if(!isset($source[$table])) {
|
||||||
|
$this->assertTrue(false, "Source for expectations does not contain requested table $table.");
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
$out[$table] = [
|
||||||
|
'columns' => [],
|
||||||
|
'rows' => [],
|
||||||
|
];
|
||||||
|
$transformations = [];
|
||||||
|
foreach($columns as $target => $col) {
|
||||||
|
if(!isset($source[$table]['columns'][$col])) {
|
||||||
|
$this->assertTrue(false, "Source for expectations does not contain requested column $col of table $table.");
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
$found = array_search($col, array_keys($source[$table]['columns']));
|
||||||
|
$transformations[$found] = $target;
|
||||||
|
$out[$table]['columns'][$col] = $source[$table]['columns'][$col];
|
||||||
|
}
|
||||||
|
foreach($source[$table]['rows'] as $sourceRow) {
|
||||||
|
$newRow = [];
|
||||||
|
foreach($transformations as $from => $to) {
|
||||||
|
$newRow[$to] = $sourceRow[$from];
|
||||||
|
}
|
||||||
|
$out[$table]['rows'][] = $newRow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $out;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -38,8 +38,8 @@
|
||||||
<file>Db/SQLite3/TestDbUpdateSQLite3.php</file>
|
<file>Db/SQLite3/TestDbUpdateSQLite3.php</file>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
|
|
||||||
<testsuite name="Database functions">
|
<testsuite name="SQLite3 database functions">
|
||||||
<file>Db/TestDatabase.php</file>
|
<file>Db/SQLite3/Database/TestDatabaseUser.php</file>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
|
|
||||||
<testsuite name="NextCloud News API">
|
<testsuite name="NextCloud News API">
|
||||||
|
|
Loading…
Reference in a new issue