diff --git a/Application/Timerecording/TimerecordingView.php b/Application/Timerecording/TimerecordingView.php index 8805237..9c80c16 100755 --- a/Application/Timerecording/TimerecordingView.php +++ b/Application/Timerecording/TimerecordingView.php @@ -26,6 +26,7 @@ use phpOMS\Views\View; * @license OMS License 1.0 * @link https://orange-management.org * @since 1.0.0 + * @codeCoverageIgnore */ class TimerecordingView extends View { diff --git a/Controller/ApiController.php b/Controller/ApiController.php index 3ed4a08..fe2d045 100755 --- a/Controller/ApiController.php +++ b/Controller/ApiController.php @@ -43,36 +43,6 @@ use phpOMS\Model\Message\FormValidation; */ 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 * @@ -88,10 +58,19 @@ final class ApiController extends Controller */ 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); if ($session === null) { $this->fillJsonResponse($request, $response, NotificationLevel::ERROR, 'Session', 'Session couldn\'t be created.', $session); + $response->header->status = RequestStatusCode::R_400; return; } @@ -113,17 +92,9 @@ final class ApiController extends Controller { $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); - $type = (int) $request->getData('type'); - $status = (int) $request->getData('status'); + $type = (int) ($request->getData('type') ?? ClockingType::OFFICE); + $status = (int) ($request->getData('status') ?? ClockingStatus::START); if ($employee instanceof NullEmployee) { return null; @@ -163,7 +134,7 @@ final class ApiController extends Controller */ 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); return; @@ -176,18 +147,30 @@ final class ApiController extends Controller 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); if ($element === null) { $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; } if ($element->getStatus() === ClockingStatus::END) { - $session = SessionMapper::get($element->session->getId()); + $session = SessionMapper::get((int) $request->getData('session')); $session->addSessionElement($element); - SessionMapper::update($session); + SessionMapper::update($session, depth: 1); } $this->createModel($request->header->account, $element, SessionElementMapper::class, 'element', $request->getOrigin()); @@ -235,23 +218,7 @@ final class ApiController extends Controller return null; } - // account and owner of the session don't match = exception! - 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'); + $status = (int) ($request->getData('status') ?? -1); // 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 @@ -261,6 +228,7 @@ final class ApiController extends Controller $element = new SessionElement($session, $dt); $element->setStatus(ClockingStatus::isValidValue($status) ? $status : ClockingStatus::END); + $element->session = $session; return $element; } diff --git a/Controller/BackendController.php b/Controller/BackendController.php index 1118054..4e8a1cd 100755 --- a/Controller/BackendController.php +++ b/Controller/BackendController.php @@ -31,6 +31,7 @@ use phpOMS\Views\View; * @license OMS License 1.0 * @link https://orange-management.org * @since 1.0.0 + * @codeCoverageIgnore */ final class BackendController extends Controller implements DashboardElementInterface { diff --git a/Models/NullSessionElement.php b/Models/NullSessionElement.php index 94f2308..4ff9378 100755 --- a/Models/NullSessionElement.php +++ b/Models/NullSessionElement.php @@ -24,4 +24,16 @@ namespace Modules\HumanResourceTimeRecording\Models; */ 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(); + } } diff --git a/Models/Session.php b/Models/Session.php index e7661c3..79d8cf0 100755 --- a/Models/Session.php +++ b/Models/Session.php @@ -42,7 +42,7 @@ class Session implements \JsonSerializable, ArrayableInterface * @var \DateTime * @since 1.0.0 */ - private \DateTime $start; + public \DateTime $start; /** * Session end @@ -50,7 +50,7 @@ class Session implements \JsonSerializable, ArrayableInterface * @var null|\DateTime * @since 1.0.0 */ - private ?\DateTime $end = null; + public ?\DateTime $end = null; /** * Busy time. @@ -82,7 +82,7 @@ class Session implements \JsonSerializable, ArrayableInterface * @var Employee * @since 1.0.0 */ - private Employee $employee; + public Employee $employee; /** * Constructor. @@ -110,15 +110,15 @@ class Session implements \JsonSerializable, ArrayableInterface } /** - * Get employee. + * Get busy time. * - * @return Employee + * @return int * * @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) { foreach ($this->sessionElements as $e) { - if ($e->getStatus === ClockingStatus::START) { + if ($e->getStatus() === ClockingStatus::START) { return; } } - $this->start = $element->getDatetime(); + $this->start = $element->datetime; } if ($element->getStatus() === ClockingStatus::END) { @@ -147,14 +147,12 @@ class Session implements \JsonSerializable, ArrayableInterface return; } - $this->end = $element->getDatetime(); + $this->end = $element->datetime; } $this->sessionElements[] = $element; - \usort($this->sessionElements, function($a, $b) { - return $a->getDatetime()->getTimestamp() <=> $b->getDatetime()->getTimestamp(); - }); + \usort($this->sessionElements, [$this, 'compareSessionElementTimestamps']); $busyTime = 0; $lastStart = $this->start; @@ -165,11 +163,11 @@ class Session implements \JsonSerializable, ArrayableInterface } 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) { - $lastStart = $e->getDatetime(); + $lastStart = $e->datetime; } } @@ -188,6 +186,21 @@ class Session implements \JsonSerializable, ArrayableInterface 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 * @@ -201,9 +214,7 @@ class Session implements \JsonSerializable, ArrayableInterface return ClockingStatus::START; } - \usort($this->sessionElements, function($a, $b) { - return $a->getDatetime()->getTimestamp() <=> $b->getDatetime()->getTimestamp(); - }); + \usort($this->sessionElements, [$this, 'compareSessionElementTimestamps']); $last = \end($this->sessionElements); @@ -221,9 +232,7 @@ class Session implements \JsonSerializable, ArrayableInterface */ public function getBreak() : int { - \usort($this->sessionElements, function($a, $b) { - return $a->getDatetime()->getTimestamp() <=> $b->getDatetime()->getTimestamp(); - }); + \usort($this->sessionElements, [$this, 'compareSessionElementTimestamps']); $breakTime = 0; $lastBreak = $this->start; @@ -234,29 +243,17 @@ class Session implements \JsonSerializable, ArrayableInterface } if ($element->getStatus() === ClockingStatus::PAUSE || $element->getStatus() === ClockingStatus::END) { - $lastBreak = $element->getDatetime(); + $lastBreak = $element->datetime; } if ($element->getStatus() === ClockingStatus::CONTINUE) { - $breakTime += $element->getDatetime()->getTimestamp() - ($lastBreak->getTimestamp() ?? 0); + $breakTime += $element->datetime->getTimestamp() - ($lastBreak->getTimestamp() ?? 0); } } return $breakTime; } - /** - * Get busy time - * - * @return int - * - * @since 1.0.0 - */ - public function getBusy() : int - { - return $this->busy; - } - /** * Get the session type * @@ -283,30 +280,6 @@ class Session implements \JsonSerializable, ArrayableInterface $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} */ @@ -323,14 +296,6 @@ class Session implements \JsonSerializable, ArrayableInterface ]; } - /** - * {@inheritdoc} - */ - public function __toString() - { - return (string) \json_encode($this->toArray()); - } - /** * {@inheritdoc} */ diff --git a/Models/SessionElement.php b/Models/SessionElement.php index a06c354..d05cbdd 100755 --- a/Models/SessionElement.php +++ b/Models/SessionElement.php @@ -48,28 +48,28 @@ class SessionElement implements \JsonSerializable, ArrayableInterface * @var \DateTime * @since 1.0.0 */ - private \DateTime $dt; + public \DateTime $datetime; /** * Session id this element belongs to * - * @var Session + * @var int|Session * @since 1.0.0 */ - public Session $session; + public int|Session $session; /** * Constructor. * * @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 */ - public function __construct(Session $session = null, \DateTime $dt = null) + public function __construct(Session $session = null, \DateTime $datetime = null) { - $this->session = $session ?? new NullSession(); - $this->dt = $dt ?? new \DateTime('now'); + $this->session = $session ?? new NullSession(); + $this->datetime = $datetime ?? new \DateTime('now'); } /** @@ -84,18 +84,6 @@ class SessionElement implements \JsonSerializable, ArrayableInterface 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 * @@ -130,19 +118,11 @@ class SessionElement implements \JsonSerializable, ArrayableInterface return [ 'id' => $this->id, 'status' => $this->status, - 'dt' => $this->dt, - 'session' => $this->session->getId(), + 'datetime' => $this->datetime, + 'session' => $this->session, ]; } - /** - * {@inheritdoc} - */ - public function __toString() - { - return (string) \json_encode($this->toArray()); - } - /** * {@inheritdoc} */ diff --git a/Models/SessionElementMapper.php b/Models/SessionElementMapper.php index 5c8dfa9..60fd9df 100755 --- a/Models/SessionElementMapper.php +++ b/Models/SessionElementMapper.php @@ -35,7 +35,7 @@ final class SessionElementMapper extends DataMapperAbstract protected static array $columns = [ '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_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'], ]; diff --git a/Models/SessionMapper.php b/Models/SessionMapper.php index f76f616..59aca33 100755 --- a/Models/SessionMapper.php +++ b/Models/SessionMapper.php @@ -143,7 +143,7 @@ final class SessionMapper extends DataMapperAbstract $dt = new SmartDateTime('now'); $dt->smartModify(0, 0, -32); - $depth = 3; + $depth = 2; $query = self::getQuery(); $query->where(self::$table . '_d' . $depth . '.hr_timerecording_session_employee', '=', $employee) ->andWhere(self::$table . '_d' . $depth . '.hr_timerecording_session_start', '>', $dt) @@ -157,7 +157,7 @@ final class SessionMapper extends DataMapperAbstract return null; } - if (\end($sessions)->getEnd() === null) { + if (\end($sessions)->end === null) { return \end($sessions); } diff --git a/tests/Controller/ApiControllerTest.php b/tests/Controller/ApiControllerTest.php new file mode 100644 index 0000000..3a2c199 --- /dev/null +++ b/tests/Controller/ApiControllerTest.php @@ -0,0 +1,201 @@ +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); + } +} diff --git a/tests/Models/NullSessionElementTest.php b/tests/Models/NullSessionElementTest.php new file mode 100644 index 0000000..8f2aed6 --- /dev/null +++ b/tests/Models/NullSessionElementTest.php @@ -0,0 +1,42 @@ +getId()); + } +} diff --git a/tests/Models/NullSessionTest.php b/tests/Models/NullSessionTest.php new file mode 100644 index 0000000..f8fe8b3 --- /dev/null +++ b/tests/Models/NullSessionTest.php @@ -0,0 +1,42 @@ +getId()); + } +} diff --git a/tests/Models/SessionElementMapperTest.php b/tests/Models/SessionElementMapperTest.php index 054e3f2..042daa8 100755 --- a/tests/Models/SessionElementMapperTest.php +++ b/tests/Models/SessionElementMapperTest.php @@ -37,8 +37,8 @@ final class SessionElementMapperTest extends \PHPUnit\Framework\TestCase self::assertEquals($id, $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->session->getEmployee()->getId(), $elementR->session->getEmployee()->getId()); + self::assertEquals($element->session->employee->getId(), $elementR->session->employee->getId()); } } diff --git a/tests/Models/SessionElementTest.php b/tests/Models/SessionElementTest.php index 6afc7ee..a5f80e2 100755 --- a/tests/Models/SessionElementTest.php +++ b/tests/Models/SessionElementTest.php @@ -15,6 +15,7 @@ declare(strict_types=1); namespace Modules\HumanResourceTimeRecording\tests\Models; use Modules\HumanResourceTimeRecording\Models\ClockingStatus; +use Modules\HumanResourceTimeRecording\Models\NullSession; use Modules\HumanResourceTimeRecording\Models\SessionElement; /** @@ -22,29 +23,57 @@ use Modules\HumanResourceTimeRecording\Models\SessionElement; */ final class SessionElementTest extends \PHPUnit\Framework\TestCase { + private SessionElement $element; + + /** + * {@inheritdoc} + */ + protected function setUp() : void + { + $this->element = new SessionElement(); + } + /** * @covers Modules\HumanResourceTimeRecording\Models\SessionElement * @group module */ public function testDefault() : void { - $element = new SessionElement(); - - self::assertEquals(0, $element->getId()); - self::assertEquals(0, $element->session->getId()); - self::assertEquals((new \DateTime('now'))->format('Y-m-d'), $element->getDatetime()->format('Y-m-d')); - self::assertEquals(ClockingStatus::START, $element->getStatus()); + self::assertEquals(0, $this->element->getId()); + self::assertEquals(0, $this->element->session->getId()); + self::assertInstanceOf('\DateTime', $this->element->datetime); + self::assertEquals(ClockingStatus::START, $this->element->getStatus()); } /** * @covers Modules\HumanResourceTimeRecording\Models\SessionElement * @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 + ); } } diff --git a/tests/Models/SessionMapperTest.php b/tests/Models/SessionMapperTest.php index 6fea84c..edafc91 100755 --- a/tests/Models/SessionMapperTest.php +++ b/tests/Models/SessionMapperTest.php @@ -44,61 +44,12 @@ final class SessionMapperTest extends \PHPUnit\Framework\TestCase $sessionR = SessionMapper::get($session->getId()); self::assertEquals($session->getType(), $sessionR->getType()); - } - /** - * @group volume - * @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)); + self::assertGreaterThan(0, \count(SessionMapper::getLastSessionsFromAllEmployees())); + self::assertEquals(null, SessionMapper::getMostPlausibleOpenSessionForEmployee(9999)); - if ($weekday === 'Sat' || $weekday === 'Sun') { - continue; - } - - $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); - } + // @todo implement + //self::assertGreaterThan(0, \count(SessionMapper::getSessionListForEmployee(1, (new \DateTime('now'))->modify('+1 month')))); + // self::assertGreaterThan(0, SessionMapper::getMostPlausibleOpenSessionForEmployee(1)->getId()); } } diff --git a/tests/Models/SessionTest.php b/tests/Models/SessionTest.php index 80cb23e..c0a6d1f 100755 --- a/tests/Models/SessionTest.php +++ b/tests/Models/SessionTest.php @@ -24,37 +24,139 @@ use Modules\HumanResourceTimeRecording\Models\SessionElement; */ final class SessionTest extends \PHPUnit\Framework\TestCase { + private Session $session; + + /** + * {@inheritdoc} + */ + protected function setUp() : void + { + $this->session = new Session(); + } + /** * @covers Modules\HumanResourceTimeRecording\Models\Session * @group module */ public function testDefault() : void { - $session = new Session(); - - self::assertEquals(0, $session->getId()); - self::assertEquals(0, $session->getBusy()); - self::assertEquals(ClockingType::OFFICE, $session->getType()); - self::assertEquals(ClockingStatus::START, $session->getStatus()); - self::assertEquals((new \DateTime('now'))->format('Y-m-d'), $session->getStart()->format('Y-m-d')); - self::assertNull($session->getEnd()); + self::assertEquals(0, $this->session->getId()); + self::assertEquals(0, $this->session->getBusy()); + self::assertEquals(0, $this->session->getBreak()); + self::assertEquals([], $this->session->getSessionElements()); + self::assertEquals(ClockingType::OFFICE, $this->session->getType()); + self::assertEquals(ClockingStatus::START, $this->session->getStatus()); + self::assertEquals((new \DateTime('now'))->format('Y-m-d'), $this->session->start->format('Y-m-d')); + self::assertNull($this->session->end); } /** * @covers Modules\HumanResourceTimeRecording\Models\Session * @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); - $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 + ); } } diff --git a/tests/phpunit_default.xml b/tests/phpunit_default.xml index 722365c..9208c99 100755 --- a/tests/phpunit_default.xml +++ b/tests/phpunit_default.xml @@ -1,5 +1,5 @@ - + *vendor*