Browse Source

First basic test for User class

As the User class depends on the database and this has yet to be tested (though I'm fairly certain it works), the mock driver also acts as a mock of the required database functions, with both instances sharing a common storage structure. Later test series should separate the two.
microsub
J. King 7 years ago
parent
commit
e6feb8de8d
  1. 6
      lib/Database.php
  2. 2
      lib/User.php
  3. 16
      tests/User/TestUser.php
  4. 45
      tests/lib/User/DriverInternalMock.php

6
lib/Database.php

@ -175,7 +175,7 @@ class Database {
if(!$this->data->user->authorize($user, __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); if(!$this->data->user->authorize($user, __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
if($this->userExists($user)) return false; if($this->userExists($user)) return false;
if(strlen($password) > 0) $password = password_hash($password, \PASSWORD_DEFAULT); if(strlen($password) > 0) $password = password_hash($password, \PASSWORD_DEFAULT);
$this->db->prepare("INSERT INTO newssync_users(id,password) values(?,?)", "str", "str", "str")->run($user,$password,$admin); $this->db->prepare("INSERT INTO newssync_users(id,password) values(?,?)", "str", "str")->run($user,$password);
return true; return true;
} }
@ -211,7 +211,7 @@ class Database {
public function userPasswordSet(string $user, string $password = null): bool { public function userPasswordSet(string $user, string $password = null): bool {
if(!$this->data->user->authorize($user, __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); if(!$this->data->user->authorize($user, __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]);
if(!$this->userExists($user)) return false; if(!$this->userExists($user)) return false;
if(strlen($password > 0)) $password = password_hash($password); if(strlen($password > 0)) $password = password_hash($password, \PASSWORD_DEFAULT);
$this->db->prepare("UPDATE newssync_users set password = ? where id is ?", "str", "str")->run($password, $user); $this->db->prepare("UPDATE newssync_users set password = ? where id is ?", "str", "str")->run($password, $user);
return true; return true;
} }
@ -244,7 +244,7 @@ class Database {
} }
public function userRightsSet(string $user, int $rights): bool { public function userRightsSet(string $user, int $rights): bool {
if(!$this->data->user->authorize($user, __FUNCTION__)) throw new User\ExceptionAuthz("notAuthorized", ["action" => __FUNCTION__, "user" => $user]); if(!$this->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)) return false;
$this->db->prepare("UPDATE newssync_users set rights = ? where id is ?", "int", "str")->run($rights, $user); $this->db->prepare("UPDATE newssync_users set rights = ? where id is ?", "int", "str")->run($rights, $user);
return true; return true;

2
lib/User.php

@ -144,7 +144,7 @@ class User {
if($this->u->driverFunctions("userAdd") != User\Driver::FUNC_INTERNAL) { if($this->u->driverFunctions("userAdd") != User\Driver::FUNC_INTERNAL) {
if(!$this->data->user->authorize($user, "userAdd")) throw new User\ExceptionAuthz("notAuthorized", ["action" => "userAdd", "user" => $user]); if(!$this->data->user->authorize($user, "userAdd")) throw new User\ExceptionAuthz("notAuthorized", ["action" => "userAdd", "user" => $user]);
} }
if($this->exists($user)) return false; if($this->exists($user)) throw new User\Exception("alreadyExists", ["action" => "userAdd", "user" => $user]);
$out = $this->u->userAdd($user, $password); $out = $this->u->userAdd($user, $password);
if($out && $this->u->driverFunctions("userAdd") != User\Driver::FUNC_INTERNAL) { if($out && $this->u->driverFunctions("userAdd") != User\Driver::FUNC_INTERNAL) {
try { try {

16
tests/User/TestUser.php

@ -9,9 +9,23 @@ class TestUser extends \PHPUnit\Framework\TestCase {
protected $data; protected $data;
function setUp() { function setUp() {
$drv = Test\User\DriverInternalMock::class;
$conf = new Conf(); $conf = new Conf();
$conf->userDriver = Test\User\DriverInternalMock::class; $conf->userDriver = $drv;
$conf->userAuthPreferHTTP = true;
$this->data = new Test\RuntimeData($conf); $this->data = new Test\RuntimeData($conf);
$this->data->user = new User($this->data); $this->data->user = new User($this->data);
$this->data->db = new $drv($this->data);
Test\User\DriverInternalMock::$db = [];
$_SERVER['PHP_AUTH_USER'] = "john.doe@example.com";
$_SERVER['PHP_AUTH_PW'] = "secret";
}
function testAddingAUser() {
$this->assertCount(0,$this->data->user->list());
$this->data->user->add($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
$this->assertCount(1,$this->data->user->list());
$this->assertException("alreadyExists", "User");
$this->data->user->add($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']);
} }
} }

45
tests/lib/User/DriverInternalMock.php

@ -5,8 +5,8 @@ use JKingWeb\NewsSync\Lang, JKingWeb\NewsSync\User\Driver;
final class DriverInternalMock implements Driver { final class DriverInternalMock implements Driver {
public static $db = [];
protected $data; protected $data;
protected $db;
protected $functions = [ protected $functions = [
"auth" => Driver::FUNC_INTERNAL, "auth" => Driver::FUNC_INTERNAL,
"authorize" => Driver::FUNC_INTERNAL, "authorize" => Driver::FUNC_INTERNAL,
@ -43,47 +43,74 @@ final class DriverInternalMock implements Driver {
} }
function auth(string $user, string $password): bool { function auth(string $user, string $password): bool {
return true; if(!$this->userExists($user)) return false;
if(password_verify($password, static::$db[$user]['password'])) return true;
return false;
} }
function authorize(string $affectedUser, string $action, int $newRightsLevel = 0): bool { function authorize(string $affectedUser, string $action, int $newRightsLevel = 0): bool {
if($affectedUser==$this->data->user->id) return true; return true;
return false;
} }
function userExists(string $user): bool { function userExists(string $user): bool {
return true; return array_key_exists($user, static::$db);
} }
function userAdd(string $user, string $password = null): bool { function userAdd(string $user, string $password = null): bool {
if($this->userExists($user)) return false;
$u = [
'password' => $password ? password_hash($password, \PASSWORD_DEFAULT) : null,
'rights' => Driver::RIGHTS_NONE,
];
static::$db[$user] = $u;
return true; return true;
} }
function userRemove(string $user): bool { function userRemove(string $user): bool {
if(!$this->userExists($user)) return false;
unset(static::$db[$user]);
return true; return true;
} }
function userList(string $domain = null): array { function userList(string $domain = null): array {
return []; $list = array_keys(static::$db);
if($domain===null) {
return $list;
} else {
$suffix = '@'.$domain;
$len = -1 * strlen($suffix);
return array_filter($list, function($user) use($suffix, $len) {
return substr_compare($user, $suffix, $len);
});
}
} }
function userPasswordSet(string $user, string $newPassword, string $oldPassword): bool { function userPasswordSet(string $user, string $newPassword, string $oldPassword): bool {
if(!$this->userExists($user)) return false;
if(!$this->auth($user, $oldPassword)) return false;
static::$db[$user]['password'] = password_hash($newPassword, \PASSWORD_DEFAULT);
return true; return true;
} }
function userPropertiesGet(string $user): array { function userPropertiesGet(string $user): array {
return []; if(!$this->userExists($user)) return [];
return static::$db[$user];
} }
function userPropertiesSet(string $user, array $properties): array { function userPropertiesSet(string $user, array $properties): array {
return []; if(!$this->userExists($user)) return [];
static::$db[$user] = array_merge(static::$db[$user], $properties);
return $this->userPropertiesGet($user);
} }
function userRightsGet(string $user): int { function userRightsGet(string $user): int {
return 0; if(!$this->userExists($user)) return Driver::RIGHTS_NONE;
return static::$db[$user]['rights'];
} }
function userRightsSet(string $user, int $level): bool { function userRightsSet(string $user, int $level): bool {
if(!$this->userExists($user)) return false;
static::$db[$user]['rights'] = $level;
return true; return true;
} }
} }
Loading…
Cancel
Save