add unit tests

This commit is contained in:
Dennis Eichhorn 2021-11-02 21:57:09 +01:00
parent d67f2c0527
commit 4f878b239d
16 changed files with 535 additions and 241 deletions

View File

@ -26,6 +26,7 @@ use phpOMS\Views\View;
* @license OMS License 1.0 * @license OMS License 1.0
* @link https://orange-management.org * @link https://orange-management.org
* @since 1.0.0 * @since 1.0.0
* @codeCoverageIgnore
*/ */
class TimerecordingView extends View class TimerecordingView extends View
{ {

View File

@ -43,36 +43,6 @@ use phpOMS\Model\Message\FormValidation;
*/ */
final class ApiController extends Controller final class ApiController extends Controller
{ {
/**
* Api method to get multiple sessions for an employee
*
* @param RequestAbstract $request Request
* @param ResponseAbstract $response Response
* @param mixed $data Generic data
*
* @return void
*
* @api
*
* @since 1.0.0
*/
public function apiSessionsListForEmployeeGet(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
{
$account = (int) ($request->getData('account') ?? $request->header->account);
if ($request->getData('account') !== null) {
if (!$this->app->accountManager->get($request->header->account)->hasPermission(
PermissionType::READ, $this->app->orgId, $this->app->appName, self::NAME, PermissionState::SESSION_FOREIGN
)) {
$this->fillJsonResponse($request, $response, NotificationLevel::HIDDEN, '', '', []);
}
}
$employee = EmployeeMapper::getFromAccount($account);
$sessions = SessionMapper::getSessionListForEmployee($employee->getId(), new \DateTime($request->getData('start') ?? 'now'), (int) ($request->getData('session') ?? 0), 50);
$this->fillJsonResponse($request, $response, NotificationLevel::HIDDEN, '', '', $sessions);
}
/** /**
* Api method to create a session * Api method to create a session
* *
@ -88,10 +58,19 @@ final class ApiController extends Controller
*/ */
public function apiSessionCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void public function apiSessionCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
{ {
if ($request->getData('account') !== null && !$this->app->accountManager->get($request->header->account)->hasPermission(
PermissionType::CREATE, $this->app->orgId, $this->app->appName, self::NAME, PermissionState::SESSION_FOREIGN
)) {
$response->header->status = RequestStatusCode::R_403;
return;
}
$session = $this->createSessionFromRequest($request); $session = $this->createSessionFromRequest($request);
if ($session === null) { if ($session === null) {
$this->fillJsonResponse($request, $response, NotificationLevel::ERROR, 'Session', 'Session couldn\'t be created.', $session); $this->fillJsonResponse($request, $response, NotificationLevel::ERROR, 'Session', 'Session couldn\'t be created.', $session);
$response->header->status = RequestStatusCode::R_400;
return; return;
} }
@ -113,17 +92,9 @@ final class ApiController extends Controller
{ {
$account = (int) ($request->getData('account') ?? $request->header->account); $account = (int) ($request->getData('account') ?? $request->header->account);
if ($request->getData('account') !== null) {
if (!$this->app->accountManager->get($request->header->account)->hasPermission(
PermissionType::CREATE, $this->app->orgId, $this->app->appName, self::NAME, PermissionState::SESSION_FOREIGN
)) {
return null;
}
}
$employee = EmployeeMapper::getFromAccount($account); $employee = EmployeeMapper::getFromAccount($account);
$type = (int) $request->getData('type'); $type = (int) ($request->getData('type') ?? ClockingType::OFFICE);
$status = (int) $request->getData('status'); $status = (int) ($request->getData('status') ?? ClockingStatus::START);
if ($employee instanceof NullEmployee) { if ($employee instanceof NullEmployee) {
return null; return null;
@ -163,7 +134,7 @@ final class ApiController extends Controller
*/ */
public function apiSessionElementCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void public function apiSessionElementCreate(RequestAbstract $request, ResponseAbstract $response, $data = null) : void
{ {
if ((int) $request->getData('status') === ClockingStatus::START) { if ((int) ($request->getData('status') ?? -1) === ClockingStatus::START) {
$this->apiSessionCreate($request, $response); $this->apiSessionCreate($request, $response);
return; return;
@ -176,18 +147,30 @@ final class ApiController extends Controller
return; return;
} }
if ($request->getData('account') !== null && ((int) $request->getData('account')) !== $request->header->account
) {
if (!$this->app->accountManager->get($request->header->account)->hasPermission(
PermissionType::CREATE, $this->app->orgId, $this->app->appName, self::NAME, PermissionState::SESSION_ELEMENT_FOREIGN
)) {
$response->header->status = RequestStatusCode::R_403;
return;
}
}
$element = $this->createSessionElementFromRequest($request); $element = $this->createSessionElementFromRequest($request);
if ($element === null) { if ($element === null) {
$this->fillJsonResponse($request, $response, NotificationLevel::ERROR, 'Session Element', 'You cannot create a session element for another person!', $element); $this->fillJsonResponse($request, $response, NotificationLevel::ERROR, 'Session Element', 'You cannot create a session element for another person!', $element);
$response->header->status = RequestStatusCode::R_400;
return; return;
} }
if ($element->getStatus() === ClockingStatus::END) { if ($element->getStatus() === ClockingStatus::END) {
$session = SessionMapper::get($element->session->getId()); $session = SessionMapper::get((int) $request->getData('session'));
$session->addSessionElement($element); $session->addSessionElement($element);
SessionMapper::update($session); SessionMapper::update($session, depth: 1);
} }
$this->createModel($request->header->account, $element, SessionElementMapper::class, 'element', $request->getOrigin()); $this->createModel($request->header->account, $element, SessionElementMapper::class, 'element', $request->getOrigin());
@ -235,23 +218,7 @@ final class ApiController extends Controller
return null; return null;
} }
// account and owner of the session don't match = exception! $status = (int) ($request->getData('status') ?? -1);
if ($session->getEmployee()->profile->account->getId() !== $account) {
return null;
}
// check permissions to edit session and create session element of a foreign account
if ($request->getData('account') !== null
|| $session->getEmployee()->profile->account->getId() !== $request->header->account
) {
if (!$this->app->accountManager->get($request->header->account)->hasPermission(
PermissionType::CREATE, $this->app->orgId, $this->app->appName, self::NAME, PermissionState::SESSION_ELEMENT_FOREIGN
)) {
return null;
}
}
$status = (int) $request->getData('status');
// a custom datetime can only be set if the user is allowed to create a session for a foreign account or if the session is a vacation // a custom datetime can only be set if the user is allowed to create a session for a foreign account or if the session is a vacation
$dt = $request->getData('datetime') !== null $dt = $request->getData('datetime') !== null
@ -261,6 +228,7 @@ final class ApiController extends Controller
$element = new SessionElement($session, $dt); $element = new SessionElement($session, $dt);
$element->setStatus(ClockingStatus::isValidValue($status) ? $status : ClockingStatus::END); $element->setStatus(ClockingStatus::isValidValue($status) ? $status : ClockingStatus::END);
$element->session = $session;
return $element; return $element;
} }

View File

@ -31,6 +31,7 @@ use phpOMS\Views\View;
* @license OMS License 1.0 * @license OMS License 1.0
* @link https://orange-management.org * @link https://orange-management.org
* @since 1.0.0 * @since 1.0.0
* @codeCoverageIgnore
*/ */
final class BackendController extends Controller implements DashboardElementInterface final class BackendController extends Controller implements DashboardElementInterface
{ {

View File

@ -24,4 +24,16 @@ namespace Modules\HumanResourceTimeRecording\Models;
*/ */
final class NullSessionElement extends SessionElement final class NullSessionElement extends SessionElement
{ {
/**
* Constructor
*
* @param int $id Model id
*
* @since 1.0.0
*/
public function __construct(int $id = 0)
{
$this->id = $id;
parent::__construct();
}
} }

View File

@ -42,7 +42,7 @@ class Session implements \JsonSerializable, ArrayableInterface
* @var \DateTime * @var \DateTime
* @since 1.0.0 * @since 1.0.0
*/ */
private \DateTime $start; public \DateTime $start;
/** /**
* Session end * Session end
@ -50,7 +50,7 @@ class Session implements \JsonSerializable, ArrayableInterface
* @var null|\DateTime * @var null|\DateTime
* @since 1.0.0 * @since 1.0.0
*/ */
private ?\DateTime $end = null; public ?\DateTime $end = null;
/** /**
* Busy time. * Busy time.
@ -82,7 +82,7 @@ class Session implements \JsonSerializable, ArrayableInterface
* @var Employee * @var Employee
* @since 1.0.0 * @since 1.0.0
*/ */
private Employee $employee; public Employee $employee;
/** /**
* Constructor. * Constructor.
@ -110,15 +110,15 @@ class Session implements \JsonSerializable, ArrayableInterface
} }
/** /**
* Get employee. * Get busy time.
* *
* @return Employee * @return int
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function getEmployee() : Employee public function getBusy() : int
{ {
return $this->employee; return $this->busy;
} }
/** /**
@ -134,12 +134,12 @@ class Session implements \JsonSerializable, ArrayableInterface
{ {
if ($element->getStatus() === ClockingStatus::START) { if ($element->getStatus() === ClockingStatus::START) {
foreach ($this->sessionElements as $e) { foreach ($this->sessionElements as $e) {
if ($e->getStatus === ClockingStatus::START) { if ($e->getStatus() === ClockingStatus::START) {
return; return;
} }
} }
$this->start = $element->getDatetime(); $this->start = $element->datetime;
} }
if ($element->getStatus() === ClockingStatus::END) { if ($element->getStatus() === ClockingStatus::END) {
@ -147,14 +147,12 @@ class Session implements \JsonSerializable, ArrayableInterface
return; return;
} }
$this->end = $element->getDatetime(); $this->end = $element->datetime;
} }
$this->sessionElements[] = $element; $this->sessionElements[] = $element;
\usort($this->sessionElements, function($a, $b) { \usort($this->sessionElements, [$this, 'compareSessionElementTimestamps']);
return $a->getDatetime()->getTimestamp() <=> $b->getDatetime()->getTimestamp();
});
$busyTime = 0; $busyTime = 0;
$lastStart = $this->start; $lastStart = $this->start;
@ -165,11 +163,11 @@ class Session implements \JsonSerializable, ArrayableInterface
} }
if ($e->getStatus() === ClockingStatus::PAUSE || $e->getStatus() === ClockingStatus::END) { if ($e->getStatus() === ClockingStatus::PAUSE || $e->getStatus() === ClockingStatus::END) {
$busyTime += $e->getDatetime()->getTimestamp() - $lastStart->getTimestamp(); $busyTime += $e->datetime->getTimestamp() - $lastStart->getTimestamp();
} }
if ($e->getStatus() === ClockingStatus::CONTINUE) { if ($e->getStatus() === ClockingStatus::CONTINUE) {
$lastStart = $e->getDatetime(); $lastStart = $e->datetime;
} }
} }
@ -188,6 +186,21 @@ class Session implements \JsonSerializable, ArrayableInterface
return $this->sessionElements; return $this->sessionElements;
} }
/**
* Compare session selements
*
* @param SessionElement $a First session element
* @param SessionElement $b Second session element
*
* @return int
*
* @since 1.0.0
*/
private function compareSessionElementTimestamps(SessionElement $a, SessionElement $b) : int
{
return $a->datetime->getTimestamp() <=> $b->datetime->getTimestamp();
}
/** /**
* Get the status of the last session element * Get the status of the last session element
* *
@ -201,9 +214,7 @@ class Session implements \JsonSerializable, ArrayableInterface
return ClockingStatus::START; return ClockingStatus::START;
} }
\usort($this->sessionElements, function($a, $b) { \usort($this->sessionElements, [$this, 'compareSessionElementTimestamps']);
return $a->getDatetime()->getTimestamp() <=> $b->getDatetime()->getTimestamp();
});
$last = \end($this->sessionElements); $last = \end($this->sessionElements);
@ -221,9 +232,7 @@ class Session implements \JsonSerializable, ArrayableInterface
*/ */
public function getBreak() : int public function getBreak() : int
{ {
\usort($this->sessionElements, function($a, $b) { \usort($this->sessionElements, [$this, 'compareSessionElementTimestamps']);
return $a->getDatetime()->getTimestamp() <=> $b->getDatetime()->getTimestamp();
});
$breakTime = 0; $breakTime = 0;
$lastBreak = $this->start; $lastBreak = $this->start;
@ -234,29 +243,17 @@ class Session implements \JsonSerializable, ArrayableInterface
} }
if ($element->getStatus() === ClockingStatus::PAUSE || $element->getStatus() === ClockingStatus::END) { if ($element->getStatus() === ClockingStatus::PAUSE || $element->getStatus() === ClockingStatus::END) {
$lastBreak = $element->getDatetime(); $lastBreak = $element->datetime;
} }
if ($element->getStatus() === ClockingStatus::CONTINUE) { if ($element->getStatus() === ClockingStatus::CONTINUE) {
$breakTime += $element->getDatetime()->getTimestamp() - ($lastBreak->getTimestamp() ?? 0); $breakTime += $element->datetime->getTimestamp() - ($lastBreak->getTimestamp() ?? 0);
} }
} }
return $breakTime; return $breakTime;
} }
/**
* Get busy time
*
* @return int
*
* @since 1.0.0
*/
public function getBusy() : int
{
return $this->busy;
}
/** /**
* Get the session type * Get the session type
* *
@ -283,30 +280,6 @@ class Session implements \JsonSerializable, ArrayableInterface
$this->type = $type; $this->type = $type;
} }
/**
* Return session start
*
* @return \DateTime
*
* @since 1.0.0
*/
public function getStart() : \DateTime
{
return $this->start;
}
/**
* Return session end
*
* @return null|\DateTime
*
* @since 1.0.0
*/
public function getEnd() : ?\DateTime
{
return $this->end;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
@ -323,14 +296,6 @@ class Session implements \JsonSerializable, ArrayableInterface
]; ];
} }
/**
* {@inheritdoc}
*/
public function __toString()
{
return (string) \json_encode($this->toArray());
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@ -48,28 +48,28 @@ class SessionElement implements \JsonSerializable, ArrayableInterface
* @var \DateTime * @var \DateTime
* @since 1.0.0 * @since 1.0.0
*/ */
private \DateTime $dt; public \DateTime $datetime;
/** /**
* Session id this element belongs to * Session id this element belongs to
* *
* @var Session * @var int|Session
* @since 1.0.0 * @since 1.0.0
*/ */
public Session $session; public int|Session $session;
/** /**
* Constructor. * Constructor.
* *
* @param Session $session Session id * @param Session $session Session id
* @param null|\DateTime $dt DateTime of the session element * @param null|\DateTime $datetime DateTime of the session element
* *
* @since 1.0.0 * @since 1.0.0
*/ */
public function __construct(Session $session = null, \DateTime $dt = null) public function __construct(Session $session = null, \DateTime $datetime = null)
{ {
$this->session = $session ?? new NullSession(); $this->session = $session ?? new NullSession();
$this->dt = $dt ?? new \DateTime('now'); $this->datetime = $datetime ?? new \DateTime('now');
} }
/** /**
@ -84,18 +84,6 @@ class SessionElement implements \JsonSerializable, ArrayableInterface
return $this->id; return $this->id;
} }
/**
* Get the dt data
*
* @return \DateTime
*
* @since 1.0.0
*/
public function getDatetime() : \DateTime
{
return $this->dt;
}
/** /**
* Get the session element status * Get the session element status
* *
@ -130,19 +118,11 @@ class SessionElement implements \JsonSerializable, ArrayableInterface
return [ return [
'id' => $this->id, 'id' => $this->id,
'status' => $this->status, 'status' => $this->status,
'dt' => $this->dt, 'datetime' => $this->datetime,
'session' => $this->session->getId(), 'session' => $this->session,
]; ];
} }
/**
* {@inheritdoc}
*/
public function __toString()
{
return (string) \json_encode($this->toArray());
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View File

@ -35,7 +35,7 @@ final class SessionElementMapper extends DataMapperAbstract
protected static array $columns = [ protected static array $columns = [
'hr_timerecording_session_element_id' => ['name' => 'hr_timerecording_session_element_id', 'type' => 'int', 'internal' => 'id'], 'hr_timerecording_session_element_id' => ['name' => 'hr_timerecording_session_element_id', 'type' => 'int', 'internal' => 'id'],
'hr_timerecording_session_element_status' => ['name' => 'hr_timerecording_session_element_status', 'type' => 'int', 'internal' => 'status'], 'hr_timerecording_session_element_status' => ['name' => 'hr_timerecording_session_element_status', 'type' => 'int', 'internal' => 'status'],
'hr_timerecording_session_element_dt' => ['name' => 'hr_timerecording_session_element_dt', 'type' => 'DateTime', 'internal' => 'dt'], 'hr_timerecording_session_element_dt' => ['name' => 'hr_timerecording_session_element_dt', 'type' => 'DateTime', 'internal' => 'datetime'],
'hr_timerecording_session_element_session' => ['name' => 'hr_timerecording_session_element_session', 'type' => 'int', 'internal' => 'session'], 'hr_timerecording_session_element_session' => ['name' => 'hr_timerecording_session_element_session', 'type' => 'int', 'internal' => 'session'],
]; ];

View File

@ -143,7 +143,7 @@ final class SessionMapper extends DataMapperAbstract
$dt = new SmartDateTime('now'); $dt = new SmartDateTime('now');
$dt->smartModify(0, 0, -32); $dt->smartModify(0, 0, -32);
$depth = 3; $depth = 2;
$query = self::getQuery(); $query = self::getQuery();
$query->where(self::$table . '_d' . $depth . '.hr_timerecording_session_employee', '=', $employee) $query->where(self::$table . '_d' . $depth . '.hr_timerecording_session_employee', '=', $employee)
->andWhere(self::$table . '_d' . $depth . '.hr_timerecording_session_start', '>', $dt) ->andWhere(self::$table . '_d' . $depth . '.hr_timerecording_session_start', '>', $dt)
@ -157,7 +157,7 @@ final class SessionMapper extends DataMapperAbstract
return null; return null;
} }
if (\end($sessions)->getEnd() === null) { if (\end($sessions)->end === null) {
return \end($sessions); return \end($sessions);
} }

View File

@ -0,0 +1,201 @@
<?php
/**
* Orange Management
*
* PHP Version 8.0
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace Modules\HumanResourceTimeRecording\tests\Controller;
use Model\CoreSettings;
use Modules\Admin\Models\AccountPermission;
use phpOMS\Account\Account;
use phpOMS\Account\AccountManager;
use phpOMS\Account\PermissionType;
use phpOMS\Application\ApplicationAbstract;
use phpOMS\DataStorage\Session\HttpSession;
use phpOMS\Dispatcher\Dispatcher;
use phpOMS\Event\EventManager;
use phpOMS\Message\Http\HttpRequest;
use phpOMS\Message\Http\HttpResponse;
use phpOMS\Message\Http\RequestStatusCode;
use phpOMS\Module\ModuleAbstract;
use phpOMS\Module\ModuleManager;
use phpOMS\Router\WebRouter;
use phpOMS\System\MimeType;
use phpOMS\Uri\HttpUri;
use phpOMS\Utils\TestUtils;
use Modules\HumanResourceTimeRecording\Models\ClockingStatus;
/**
* @testdox Modules\HumanResourceTimeRecording\tests\Controller\ApiControllerTest: HumanResourceTimeRecording api controller
*
* @internal
*/
final class ApiControllerTest extends \PHPUnit\Framework\TestCase
{
protected ApplicationAbstract $app;
/**
* @var \Modules\HumanResourceTimeRecording\Controller\ApiController
*/
protected ModuleAbstract $module;
/**
* {@inheritdoc}
*/
protected function setUp() : void
{
$this->app = new class() extends ApplicationAbstract
{
protected string $appName = 'Api';
};
$this->app->dbPool = $GLOBALS['dbpool'];
$this->app->orgId = 1;
$this->app->accountManager = new AccountManager($GLOBALS['session']);
$this->app->appSettings = new CoreSettings();
$this->app->moduleManager = new ModuleManager($this->app, __DIR__ . '/../../../../Modules/');
$this->app->dispatcher = new Dispatcher($this->app);
$this->app->eventManager = new EventManager($this->app->dispatcher);
$this->app->eventManager->importFromFile(__DIR__ . '/../../../../Web/Api/Hooks.php');
$this->app->sessionManager = new HttpSession(36000);
$account = new Account();
TestUtils::setMember($account, 'id', 1);
$permission = new AccountPermission();
$permission->setUnit(1);
$permission->setApp('backend');
$permission->setPermission(
PermissionType::READ
| PermissionType::CREATE
| PermissionType::MODIFY
| PermissionType::DELETE
| PermissionType::PERMISSION
);
$account->addPermission($permission);
$this->app->accountManager->add($account);
$this->app->router = new WebRouter();
$this->module = $this->app->moduleManager->get('HumanResourceTimeRecording');
TestUtils::setMember($this->module, 'app', $this->app);
}
/**
* @covers Modules\HumanResourceTimeRecording\Controller\ApiController
* @group module
*/
public function testApiSessionCR() : void
{
$response = new HttpResponse();
$request = new HttpRequest(new HttpUri(''));
$request->header->account = 1;
$this->module->apiSessionCreate($request, $response);
self::assertGreaterThan(0, $sId = $response->get('')['response']->getId());
$response = new HttpResponse();
$request = new HttpRequest(new HttpUri(''));
$request->header->account = 1;
$request->setData('session', (string) $sId);
$request->setData('status', ClockingStatus::END);
$this->module->apiSessionElementCreate($request, $response);
self::assertGreaterThan(0, $response->get('')['response']->getId());
}
/**
* @covers Modules\HumanResourceTimeRecording\Controller\ApiController
* @group module
*/
public function testApiSessionCreateInvalidPermission() : void
{
$response = new HttpResponse();
$request = new HttpRequest(new HttpUri(''));
$request->header->account = 9999;
$request->setData('account', 2);
$this->module->apiSessionCreate($request, $response);
self::assertEquals(RequestStatusCode::R_403, $response->header->status);
}
/**
* @covers Modules\HumanResourceTimeRecording\Controller\ApiController
* @group module
*/
public function testApiSessionCreateInvalidDataEmployee() : void
{
$response = new HttpResponse();
$request = new HttpRequest(new HttpUri(''));
$request->header->account = 1;
$request->setData('account', 9999);
$this->module->apiSessionCreate($request, $response);
self::assertEquals(RequestStatusCode::R_400, $response->header->status);
}
/**
* @covers Modules\HumanResourceTimeRecording\Controller\ApiController
* @group module
*/
public function testApiSessionElementCreateInvalidData() : void
{
$response = new HttpResponse();
$request = new HttpRequest(new HttpUri(''));
$request->header->account = 1;
$request->setData('invalid', 1);
$this->module->apiSessionElementCreate($request, $response);
self::assertEquals(RequestStatusCode::R_400, $response->header->status);
}
/**
* @covers Modules\HumanResourceTimeRecording\Controller\ApiController
* @group module
*/
public function testApiSessionElementCreateInvalidSessionId() : void
{
$response = new HttpResponse();
$request = new HttpRequest(new HttpUri(''));
$request->header->account = 1;
$request->setData('session', 99999);
$request->setData('status', ClockingStatus::CONTINUE);
$this->module->apiSessionElementCreate($request, $response);
self::assertEquals(RequestStatusCode::R_400, $response->header->status);
}
/**
* @covers Modules\HumanResourceTimeRecording\Controller\ApiController
* @group module
*/
public function testApiSessionElementCreateInvalidPermission() : void
{
$response = new HttpResponse();
$request = new HttpRequest(new HttpUri(''));
$request->header->account = 9999;
$request->setData('session', 1);
$request->setData('account', 1);
$this->module->apiSessionElementCreate($request, $response);
self::assertEquals(RequestStatusCode::R_403, $response->header->status);
}
}

View File

@ -0,0 +1,42 @@
<?php
/**
* Orange Management
*
* PHP Version 8.0
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace Modules\HumanResourceTimeRecording\tests\Models;
use Modules\HumanResourceTimeRecording\Models\NullSessionElement;
/**
* @internal
*/
final class NullSessionElementTest extends \PHPUnit\Framework\TestCase
{
/**
* @covers Modules\HumanResourceTimeRecording\Models\NullSessionElement
* @group framework
*/
public function testNull() : void
{
self::assertInstanceOf('\Modules\HumanResourceTimeRecording\Models\SessionElement', new NullSessionElement());
}
/**
* @covers Modules\HumanResourceTimeRecording\Models\NullSessionElement
* @group framework
*/
public function testId() : void
{
$null = new NullSessionElement(2);
self::assertEquals(2, $null->getId());
}
}

View File

@ -0,0 +1,42 @@
<?php
/**
* Orange Management
*
* PHP Version 8.0
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace Modules\HumanResourceTimeRecording\tests\Models;
use Modules\HumanResourceTimeRecording\Models\NullSession;
/**
* @internal
*/
final class NullSessionTest extends \PHPUnit\Framework\TestCase
{
/**
* @covers Modules\HumanResourceTimeRecording\Models\NullSession
* @group framework
*/
public function testNull() : void
{
self::assertInstanceOf('\Modules\HumanResourceTimeRecording\Models\Session', new NullSession());
}
/**
* @covers Modules\HumanResourceTimeRecording\Models\NullSession
* @group framework
*/
public function testId() : void
{
$null = new NullSession(2);
self::assertEquals(2, $null->getId());
}
}

View File

@ -37,8 +37,8 @@ final class SessionElementMapperTest extends \PHPUnit\Framework\TestCase
self::assertEquals($id, $element->getId()); self::assertEquals($id, $element->getId());
$elementR = SessionElementMapper::get($element->getId()); $elementR = SessionElementMapper::get($element->getId());
self::assertEquals($element->getDatetime()->format('Y-m-d'), $elementR->getDatetime()->format('Y-m-d')); self::assertEquals($element->datetime->format('Y-m-d'), $elementR->datetime->format('Y-m-d'));
self::assertEquals($element->getStatus(), $elementR->getStatus()); self::assertEquals($element->getStatus(), $elementR->getStatus());
self::assertEquals($element->session->getEmployee()->getId(), $elementR->session->getEmployee()->getId()); self::assertEquals($element->session->employee->getId(), $elementR->session->employee->getId());
} }
} }

View File

@ -15,6 +15,7 @@ declare(strict_types=1);
namespace Modules\HumanResourceTimeRecording\tests\Models; namespace Modules\HumanResourceTimeRecording\tests\Models;
use Modules\HumanResourceTimeRecording\Models\ClockingStatus; use Modules\HumanResourceTimeRecording\Models\ClockingStatus;
use Modules\HumanResourceTimeRecording\Models\NullSession;
use Modules\HumanResourceTimeRecording\Models\SessionElement; use Modules\HumanResourceTimeRecording\Models\SessionElement;
/** /**
@ -22,29 +23,57 @@ use Modules\HumanResourceTimeRecording\Models\SessionElement;
*/ */
final class SessionElementTest extends \PHPUnit\Framework\TestCase final class SessionElementTest extends \PHPUnit\Framework\TestCase
{ {
private SessionElement $element;
/**
* {@inheritdoc}
*/
protected function setUp() : void
{
$this->element = new SessionElement();
}
/** /**
* @covers Modules\HumanResourceTimeRecording\Models\SessionElement * @covers Modules\HumanResourceTimeRecording\Models\SessionElement
* @group module * @group module
*/ */
public function testDefault() : void public function testDefault() : void
{ {
$element = new SessionElement(); self::assertEquals(0, $this->element->getId());
self::assertEquals(0, $this->element->session->getId());
self::assertEquals(0, $element->getId()); self::assertInstanceOf('\DateTime', $this->element->datetime);
self::assertEquals(0, $element->session->getId()); self::assertEquals(ClockingStatus::START, $this->element->getStatus());
self::assertEquals((new \DateTime('now'))->format('Y-m-d'), $element->getDatetime()->format('Y-m-d'));
self::assertEquals(ClockingStatus::START, $element->getStatus());
} }
/** /**
* @covers Modules\HumanResourceTimeRecording\Models\SessionElement * @covers Modules\HumanResourceTimeRecording\Models\SessionElement
* @group module * @group module
*/ */
public function testSetGet() : void public function testStatusInputOutput() : void
{ {
$element = new SessionElement(); $this->element->setStatus(ClockingStatus::END);
self::assertEquals(ClockingStatus::END, $this->element->getStatus());
}
$element->setStatus(ClockingStatus::END); /**
self::assertEquals(ClockingStatus::END, $element->getStatus()); * @covers Modules\HumanResourceTimeRecording\Models\SessionElement
* @group module
*/
public function testSerialize() : void
{
$this->element->session = new NullSession(2);
$this->element->setStatus(ClockingStatus::END);
$serialized = $this->element->jsonSerialize();
unset($serialized['datetime']);
unset($serialized['session']);
self::assertEquals(
[
'id' => 0,
'status' => ClockingStatus::END,
],
$serialized
);
} }
} }

View File

@ -44,61 +44,12 @@ final class SessionMapperTest extends \PHPUnit\Framework\TestCase
$sessionR = SessionMapper::get($session->getId()); $sessionR = SessionMapper::get($session->getId());
self::assertEquals($session->getType(), $sessionR->getType()); self::assertEquals($session->getType(), $sessionR->getType());
}
/** self::assertGreaterThan(0, \count(SessionMapper::getLastSessionsFromAllEmployees()));
* @group volume self::assertEquals(null, SessionMapper::getMostPlausibleOpenSessionForEmployee(9999));
* @group module
* @coversNothing
*/
public function testVolume() : void
{
for ($i = 0; $i < 1000; ++$i) {
$day = \date('Y-m-d', \strtotime(' -' . ($i + 1) . ' day'));
$weekday = \date('D', \strtotime($day));
if ($weekday === 'Sat' || $weekday === 'Sun') { // @todo implement
continue; //self::assertGreaterThan(0, \count(SessionMapper::getSessionListForEmployee(1, (new \DateTime('now'))->modify('+1 month'))));
} // self::assertGreaterThan(0, SessionMapper::getMostPlausibleOpenSessionForEmployee(1)->getId());
$session = new Session(new NullEmployee(1));
$hourStart = \mt_rand(7, 9);
$minutesStart = \mt_rand(0, 59);
$hourEnd = \mt_rand(16, 18);
$minutesEnd = \mt_rand(0, 59);
$hourBreakStart = \mt_rand(11, 14);
$minutesBreakStart = \mt_rand(0, 59);
$breakLength = \mt_rand(5, 90);
// start
$dt = new \DateTime($day . ' ' . $hourStart . ':' . $minutesStart);
$element = new SessionElement($session, $dt);
$element->setStatus(ClockingStatus::START);
$session->addSessionElement($element);
// break start
$dt = new \DateTime($day . ' ' . $hourBreakStart . ':' . $minutesBreakStart);
$element = new SessionElement($session, $dt);
$element->setStatus(ClockingStatus::PAUSE);
$session->addSessionElement($element);
// work continue
$dt = new \DateTime($day . ' ' . ($hourBreakStart + ((int) (($minutesBreakStart + $breakLength) / 60))) . ':' . (($minutesBreakStart + $breakLength) % 60));
$element = new SessionElement($session, $dt);
$element->setStatus(ClockingStatus::CONTINUE);
$session->addSessionElement($element);
// end
$dt = new \DateTime($day . ' ' . $hourEnd . ':' . $minutesEnd);
$element = new SessionElement($session, $dt);
$element->setStatus(ClockingStatus::END);
$session->addSessionElement($element);
SessionMapper::create($session);
}
} }
} }

View File

@ -24,37 +24,139 @@ use Modules\HumanResourceTimeRecording\Models\SessionElement;
*/ */
final class SessionTest extends \PHPUnit\Framework\TestCase final class SessionTest extends \PHPUnit\Framework\TestCase
{ {
private Session $session;
/**
* {@inheritdoc}
*/
protected function setUp() : void
{
$this->session = new Session();
}
/** /**
* @covers Modules\HumanResourceTimeRecording\Models\Session * @covers Modules\HumanResourceTimeRecording\Models\Session
* @group module * @group module
*/ */
public function testDefault() : void public function testDefault() : void
{ {
$session = new Session(); self::assertEquals(0, $this->session->getId());
self::assertEquals(0, $this->session->getBusy());
self::assertEquals(0, $session->getId()); self::assertEquals(0, $this->session->getBreak());
self::assertEquals(0, $session->getBusy()); self::assertEquals([], $this->session->getSessionElements());
self::assertEquals(ClockingType::OFFICE, $session->getType()); self::assertEquals(ClockingType::OFFICE, $this->session->getType());
self::assertEquals(ClockingStatus::START, $session->getStatus()); self::assertEquals(ClockingStatus::START, $this->session->getStatus());
self::assertEquals((new \DateTime('now'))->format('Y-m-d'), $session->getStart()->format('Y-m-d')); self::assertEquals((new \DateTime('now'))->format('Y-m-d'), $this->session->start->format('Y-m-d'));
self::assertNull($session->getEnd()); self::assertNull($this->session->end);
} }
/** /**
* @covers Modules\HumanResourceTimeRecording\Models\Session * @covers Modules\HumanResourceTimeRecording\Models\Session
* @group module * @group module
*/ */
public function testSetGet() : void public function testTypeInputOutput() : void
{ {
$session = new Session(); $this->session->setType(ClockingType::VACATION);
self::assertEquals(ClockingType::VACATION, $this->session->getType());
}
$session->setType(ClockingType::VACATION); /**
self::assertEquals(ClockingType::VACATION, $session->getType()); * @covers Modules\HumanResourceTimeRecording\Models\Session
* @group module
*/
public function testStatusInputOutput() : void
{
$element = new SessionElement(null, new \DateTime('2021-10-05'));
$element->setStatus(ClockingStatus::START);
$this->session->addSessionElement($element);
$element = new SessionElement(null, new \DateTime('now')); $element = new SessionElement(null, new \DateTime('2021-10-06'));
$element->setStatus(ClockingStatus::PAUSE); $element->setStatus(ClockingStatus::PAUSE);
$session->addSessionElement($element); $this->session->addSessionElement($element);
self::assertEquals(ClockingStatus::PAUSE, $session->getStatus()); $element = new SessionElement(null, new \DateTime('2021-10-07'));
$element->setStatus(ClockingStatus::CONTINUE);
$this->session->addSessionElement($element);
self::assertEquals(ClockingStatus::CONTINUE, $this->session->getStatus());
}
/**
* @covers Modules\HumanResourceTimeRecording\Models\Session
* @group module
*/
public function testBusyBreakInputOutput() : void
{
$element = new SessionElement(null, new \DateTime('2021-10-05 02:00:00'));
$element->setStatus(ClockingStatus::START);
$this->session->addSessionElement($element);
// this is ignored because the session is already started
$element = new SessionElement(null, new \DateTime('2021-10-05 03:00:00'));
$element->setStatus(ClockingStatus::START);
$this->session->addSessionElement($element);
$element = new SessionElement(null, new \DateTime('2021-10-05 04:00:00'));
$element->setStatus(ClockingStatus::PAUSE);
$this->session->addSessionElement($element);
$element = new SessionElement(null, new \DateTime('2021-10-05 04:30:00'));
$element->setStatus(ClockingStatus::CONTINUE);
$this->session->addSessionElement($element);
$element = new SessionElement(null, new \DateTime('2021-10-05 07:00:00'));
$element->setStatus(ClockingStatus::PAUSE);
$this->session->addSessionElement($element);
$element = new SessionElement(null, new \DateTime('2021-10-05 08:30:00'));
$element->setStatus(ClockingStatus::CONTINUE);
$this->session->addSessionElement($element);
$element = new SessionElement(null, new \DateTime('2021-10-05 11:00:00'));
$element->setStatus(ClockingStatus::END);
$this->session->addSessionElement($element);
// this is ignored because the session is already stopped
$element = new SessionElement(null, new \DateTime('2021-10-05 11:30:00'));
$element->setStatus(ClockingStatus::END);
$this->session->addSessionElement($element);
self::assertEquals(2*60*60, $this->session->getBreak());
self::assertEquals(7*60*60, $this->session->getBusy());
}
/**
* @covers Modules\HumanResourceTimeRecording\Models\Session
* @group module
*/
public function testSessionElementInputOutput() : void
{
$element = new SessionElement(null, new \DateTime('now'));
$this->session->addSessionElement($element);
self::assertCount(1, $this->session->getSessionElements());
}
/**
* @covers Modules\HumanResourceTimeRecording\Models\Session
* @group module
*/
public function testSerialize() : void
{
$this->session->setType(ClockingType::VACATION);
$serialized = $this->session->jsonSerialize();
unset($serialized['start']);
unset($serialized['employee']);
self::assertEquals(
[
'id' => 0,
'end' => null,
'busy' => 0,
'type' => ClockingType::VACATION,
'elements' => [],
],
$serialized
);
} }
} }

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="Bootstrap.php" colors="true" stopOnError="true" stopOnFailure="false" stopOnIncomplete="false" stopOnSkipped="false" beStrictAboutTestsThatDoNotTestAnything="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="Bootstrap.php" colors="true" columns="120" stopOnError="true" stopOnFailure="false" stopOnIncomplete="false" stopOnSkipped="false" beStrictAboutTestsThatDoNotTestAnything="false" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<coverage includeUncoveredFiles="true" processUncoveredFiles="false"> <coverage includeUncoveredFiles="true" processUncoveredFiles="false">
<exclude> <exclude>
<directory>*vendor*</directory> <directory>*vendor*</directory>