summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/functionals/ApiTest.php10
-rw-r--r--tests/units/ActionTest.php8
-rw-r--r--tests/units/DateParserTest.php28
-rw-r--r--tests/units/HourlyRate.php43
-rw-r--r--tests/units/ProjectDuplicationTest.php4
-rw-r--r--tests/units/ProjectPermissionTest.php68
-rw-r--r--tests/units/SubtaskTest.php75
-rw-r--r--tests/units/SubtaskTimeTrackingTest.php25
-rw-r--r--tests/units/TimetableTest.php253
9 files changed, 490 insertions, 24 deletions
diff --git a/tests/functionals/ApiTest.php b/tests/functionals/ApiTest.php
index f778d1ca..9fdfd1ba 100644
--- a/tests/functionals/ApiTest.php
+++ b/tests/functionals/ApiTest.php
@@ -39,7 +39,7 @@ class Api extends PHPUnit_Framework_TestCase
{
$this->client = new JsonRPC\Client(API_URL);
$this->client->authentication('jsonrpc', API_KEY);
- //$this->client->debug = true;
+ // $this->client->debug = true;
}
private function getTaskId()
@@ -53,8 +53,12 @@ class Api extends PHPUnit_Framework_TestCase
public function testGetTimezone()
{
- $timezone = $this->client->getTimezone();
- $this->assertEquals('Europe/Paris', $timezone);
+ $this->assertEquals('Europe/Paris', $this->client->getTimezone());
+ }
+
+ public function testGetVersion()
+ {
+ $this->assertEquals('master', $this->client->getVersion());
}
public function testRemoveAll()
diff --git a/tests/units/ActionTest.php b/tests/units/ActionTest.php
index 429a181a..67957a26 100644
--- a/tests/units/ActionTest.php
+++ b/tests/units/ActionTest.php
@@ -27,7 +27,7 @@ class ActionTest extends Base
$this->assertEquals(1, $project->create(array('name' => 'unit_test')));
// We create a new action
- $this->assertTrue($action->create(array(
+ $this->assertEquals(1, $action->create(array(
'project_id' => 1,
'event_name' => Task::EVENT_MOVE_COLUMN,
'action_name' => 'TaskClose',
@@ -78,14 +78,14 @@ class ActionTest extends Base
$this->assertEquals(1, $c->create(array('name' => 'unit_test')));
// We create a new action
- $this->assertTrue($a->create(array(
+ $this->assertEquals(1, $a->create(array(
'project_id' => 1,
'event_name' => GithubWebhook::EVENT_ISSUE_OPENED,
'action_name' => 'TaskCreation',
'params' => array()
)));
- $this->assertTrue($a->create(array(
+ $this->assertEquals(2, $a->create(array(
'project_id' => 1,
'event_name' => GithubWebhook::EVENT_ISSUE_LABEL_CHANGE,
'action_name' => 'TaskAssignCategoryLabel',
@@ -95,7 +95,7 @@ class ActionTest extends Base
)
)));
- $this->assertTrue($a->create(array(
+ $this->assertEquals(3, $a->create(array(
'project_id' => 1,
'event_name' => Task::EVENT_CREATE_UPDATE,
'action_name' => 'TaskAssignColorCategory',
diff --git a/tests/units/DateParserTest.php b/tests/units/DateParserTest.php
index 5828fc48..9403063b 100644
--- a/tests/units/DateParserTest.php
+++ b/tests/units/DateParserTest.php
@@ -6,6 +6,34 @@ use Model\DateParser;
class DateParserTest extends Base
{
+ public function testDateRange()
+ {
+ $d = new DateParser($this->container);
+
+ $this->assertTrue($d->withinDateRange(new DateTime('2015-03-14 15:30:00'), new DateTime('2015-03-14 15:00:00'), new DateTime('2015-03-14 16:00:00')));
+ $this->assertFalse($d->withinDateRange(new DateTime('2015-03-14 15:30:00'), new DateTime('2015-03-14 16:00:00'), new DateTime('2015-03-14 17:00:00')));
+ }
+
+ public function testRoundSeconds()
+ {
+ $d = new DateParser($this->container);
+ $this->assertEquals('16:30', date('H:i', $d->getRoundedSeconds(strtotime('16:28'))));
+ $this->assertEquals('16:00', date('H:i', $d->getRoundedSeconds(strtotime('16:02'))));
+ $this->assertEquals('16:15', date('H:i', $d->getRoundedSeconds(strtotime('16:14'))));
+ $this->assertEquals('17:00', date('H:i', $d->getRoundedSeconds(strtotime('16:58'))));
+ }
+
+ public function testGetHours()
+ {
+ $d = new DateParser($this->container);
+
+ $this->assertEquals(1, $d->getHours(new DateTime('2015-03-14 15:00:00'), new DateTime('2015-03-14 16:00:00')));
+ $this->assertEquals(2.5, $d->getHours(new DateTime('2015-03-14 15:00:00'), new DateTime('2015-03-14 17:30:00')));
+ $this->assertEquals(2.75, $d->getHours(new DateTime('2015-03-14 15:00:00'), new DateTime('2015-03-14 17:45:00')));
+ $this->assertEquals(3, $d->getHours(new DateTime('2015-03-14 14:57:00'), new DateTime('2015-03-14 17:58:00')));
+ $this->assertEquals(3, $d->getHours(new DateTime('2015-03-14 14:57:00'), new DateTime('2015-03-14 11:58:00')));
+ }
+
public function testValidDate()
{
$d = new DateParser($this->container);
diff --git a/tests/units/HourlyRate.php b/tests/units/HourlyRate.php
new file mode 100644
index 00000000..5daf0446
--- /dev/null
+++ b/tests/units/HourlyRate.php
@@ -0,0 +1,43 @@
+<?php
+
+require_once __DIR__.'/Base.php';
+
+use Model\User;
+use Model\HourlyRate;
+
+class HourlyRateTest extends Base
+{
+ public function testCreation()
+ {
+ $hr = new HourlyRate($this->container);
+ $this->assertEquals(1, $hr->create(1, 32.4, 'EUR', '2015-01-01'));
+ $this->assertEquals(2, $hr->create(1, 42, 'CAD', '2015-02-01'));
+
+ $rates = $hr->getAllByUser(0);
+ $this->assertEmpty($rates);
+
+ $rates = $hr->getAllByUser(1);
+ $this->assertNotEmpty($rates);
+ $this->assertCount(2, $rates);
+
+ $this->assertEquals(42, $rates[0]['rate']);
+ $this->assertEquals('CAD', $rates[0]['currency']);
+ $this->assertEquals('2015-02-01', date('Y-m-d', $rates[0]['date_effective']));
+
+ $this->assertEquals(32.4, $rates[1]['rate']);
+ $this->assertEquals('EUR', $rates[1]['currency']);
+ $this->assertEquals('2015-01-01', date('Y-m-d', $rates[1]['date_effective']));
+
+ $this->assertEquals(0, $hr->getCurrentRate(0));
+ $this->assertEquals(42, $hr->getCurrentRate(1));
+
+ $this->assertTrue($hr->remove(2));
+ $this->assertEquals(32.4, $hr->getCurrentRate(1));
+
+ $this->assertTrue($hr->remove(1));
+ $this->assertEquals(0, $hr->getCurrentRate(1));
+
+ $rates = $hr->getAllByUser(1);
+ $this->assertEmpty($rates);
+ }
+}
diff --git a/tests/units/ProjectDuplicationTest.php b/tests/units/ProjectDuplicationTest.php
index b35575aa..311ecc4a 100644
--- a/tests/units/ProjectDuplicationTest.php
+++ b/tests/units/ProjectDuplicationTest.php
@@ -156,7 +156,7 @@ class ProjectDuplicationTest extends Base
$this->assertEquals(1, $p->create(array('name' => 'P1')));
- $this->assertTrue($a->create(array(
+ $this->assertEquals(1, $a->create(array(
'project_id' => 1,
'event_name' => Task::EVENT_MOVE_COLUMN,
'action_name' => 'TaskAssignCurrentUser',
@@ -186,7 +186,7 @@ class ProjectDuplicationTest extends Base
$this->assertEquals(2, $c->create(array('name' => 'C2', 'project_id' => 1)));
$this->assertEquals(3, $c->create(array('name' => 'C3', 'project_id' => 1)));
- $this->assertTrue($a->create(array(
+ $this->assertEquals(1, $a->create(array(
'project_id' => 1,
'event_name' => Task::EVENT_CREATE_UPDATE,
'action_name' => 'TaskAssignColorCategory',
diff --git a/tests/units/ProjectPermissionTest.php b/tests/units/ProjectPermissionTest.php
index 3cbd6bec..66406392 100644
--- a/tests/units/ProjectPermissionTest.php
+++ b/tests/units/ProjectPermissionTest.php
@@ -25,6 +25,22 @@ class ProjectPermissionTest extends Base
$this->assertEquals(array(), $pp->getMembers(1));
$this->assertEquals(array('Unassigned'), $pp->getMemberList(1));
+ $this->assertEmpty($pp->getMemberProjects(1));
+ $this->assertEmpty($pp->getMemberProjects(2));
+ $this->assertEmpty($pp->getMemberProjects(3));
+
+ $this->assertEmpty($pp->getMemberProjectIds(1));
+ $this->assertEmpty($pp->getMemberProjectIds(2));
+ $this->assertEmpty($pp->getMemberProjectIds(3));
+
+ $this->assertEmpty($pp->getActiveMemberProjectIds(1));
+ $this->assertEmpty($pp->getActiveMemberProjectIds(2));
+ $this->assertEmpty($pp->getActiveMemberProjectIds(3));
+
+ $this->assertEmpty($pp->getActiveMemberProjects(1));
+ $this->assertEmpty($pp->getActiveMemberProjects(2));
+ $this->assertEmpty($pp->getActiveMemberProjects(3));
+
$this->assertTrue($p->update(array('id' => 1, 'is_everybody_allowed' => 1)));
$this->assertTrue($pp->isEverybodyAllowed(1));
$this->assertTrue($pp->isUserAllowed(1, 1));
@@ -32,6 +48,32 @@ class ProjectPermissionTest extends Base
$this->assertTrue($pp->isUserAllowed(1, 3));
$this->assertEquals(array('1' => 'admin', '2' => 'unittest#1', '3' => 'unittest#2'), $pp->getMembers(1));
$this->assertEquals(array('Unassigned', '1' => 'admin', '2' => 'unittest#1', '3' => 'unittest#2'), $pp->getMemberList(1));
+
+ $this->assertNotEmpty($pp->getMemberProjects(1));
+ $this->assertNotEmpty($pp->getMemberProjects(2));
+ $this->assertNotEmpty($pp->getMemberProjects(3));
+
+ $this->assertNotEmpty($pp->getMemberProjectIds(1));
+ $this->assertNotEmpty($pp->getMemberProjectIds(2));
+ $this->assertNotEmpty($pp->getMemberProjectIds(3));
+
+ $this->assertNotEmpty($pp->getActiveMemberProjectIds(1));
+ $this->assertNotEmpty($pp->getActiveMemberProjectIds(2));
+ $this->assertNotEmpty($pp->getActiveMemberProjectIds(3));
+
+ $this->assertNotEmpty($pp->getActiveMemberProjects(1));
+ $this->assertNotEmpty($pp->getActiveMemberProjects(2));
+ $this->assertNotEmpty($pp->getActiveMemberProjects(3));
+
+ $this->assertTrue($p->disable(1));
+
+ $this->assertEmpty($pp->getActiveMemberProjectIds(1));
+ $this->assertEmpty($pp->getActiveMemberProjectIds(2));
+ $this->assertEmpty($pp->getActiveMemberProjectIds(3));
+
+ $this->assertEmpty($pp->getActiveMemberProjects(1));
+ $this->assertEmpty($pp->getActiveMemberProjects(2));
+ $this->assertEmpty($pp->getActiveMemberProjects(3));
}
public function testDisallowEverybody()
@@ -56,11 +98,23 @@ class ProjectPermissionTest extends Base
$pp = new ProjectPermission($this->container);
$user = new User($this->container);
- $user->create(array('username' => 'unittest', 'password' => 'unittest'));
+ $this->assertNotFalse($user->create(array('username' => 'unittest', 'password' => 'unittest')));
// We create a project
$this->assertEquals(1, $p->create(array('name' => 'UnitTest')));
+ $this->assertEmpty($pp->getMemberProjects(1));
+ $this->assertEmpty($pp->getMemberProjects(2));
+
+ $this->assertEmpty($pp->getMemberProjectIds(1));
+ $this->assertEmpty($pp->getMemberProjectIds(2));
+
+ $this->assertEmpty($pp->getActiveMemberProjectIds(1));
+ $this->assertEmpty($pp->getActiveMemberProjectIds(2));
+
+ $this->assertEmpty($pp->getActiveMemberProjects(1));
+ $this->assertEmpty($pp->getActiveMemberProjects(2));
+
// We allow the admin user
$this->assertTrue($pp->addMember(1, 1));
$this->assertTrue($pp->addMember(1, 2));
@@ -75,6 +129,18 @@ class ProjectPermissionTest extends Base
$this->assertEquals(array('1' => 'admin', '2' => 'unittest'), $pp->getMembers(1));
$this->assertTrue($pp->isUserAllowed(1, 1));
$this->assertTrue($pp->isUserAllowed(1, 2));
+
+ $this->assertNotEmpty($pp->getMemberProjects(1));
+ $this->assertNotEmpty($pp->getMemberProjects(2));
+
+ $this->assertNotEmpty($pp->getMemberProjectIds(1));
+ $this->assertNotEmpty($pp->getMemberProjectIds(2));
+
+ $this->assertNotEmpty($pp->getActiveMemberProjectIds(1));
+ $this->assertNotEmpty($pp->getActiveMemberProjectIds(2));
+
+ $this->assertNotEmpty($pp->getActiveMemberProjects(1));
+ $this->assertNotEmpty($pp->getActiveMemberProjects(2));
}
public function testRevokeUser()
diff --git a/tests/units/SubtaskTest.php b/tests/units/SubtaskTest.php
index 62475186..eb1a3fd3 100644
--- a/tests/units/SubtaskTest.php
+++ b/tests/units/SubtaskTest.php
@@ -11,6 +11,78 @@ use Model\User;
class SubTaskTest extends Base
{
+ public function testMoveUp()
+ {
+ $tc = new TaskCreation($this->container);
+ $s = new Subtask($this->container);
+ $p = new Project($this->container);
+
+ $this->assertEquals(1, $p->create(array('name' => 'test1')));
+ $this->assertEquals(1, $tc->create(array('title' => 'test 1', 'project_id' => 1)));
+
+ $this->assertEquals(1, $s->create(array('title' => 'subtask #1', 'task_id' => 1)));
+ $this->assertEquals(2, $s->create(array('title' => 'subtask #2', 'task_id' => 1)));
+ $this->assertEquals(3, $s->create(array('title' => 'subtask #3', 'task_id' => 1)));
+
+ $subtask = $s->getById(1);
+ $this->assertNotEmpty($subtask);
+ $this->assertEquals(1, $subtask['position']);
+
+ $subtask = $s->getById(2);
+ $this->assertNotEmpty($subtask);
+ $this->assertEquals(2, $subtask['position']);
+
+ $subtask = $s->getById(3);
+ $this->assertNotEmpty($subtask);
+ $this->assertEquals(3, $subtask['position']);
+
+ $this->assertTrue($s->moveUp(1, 2));
+
+ $subtask = $s->getById(1);
+ $this->assertNotEmpty($subtask);
+ $this->assertEquals(2, $subtask['position']);
+
+ $subtask = $s->getById(2);
+ $this->assertNotEmpty($subtask);
+ $this->assertEquals(1, $subtask['position']);
+
+ $subtask = $s->getById(3);
+ $this->assertNotEmpty($subtask);
+ $this->assertEquals(3, $subtask['position']);
+
+ $this->assertFalse($s->moveUp(1, 2));
+ }
+
+ public function testMoveDown()
+ {
+ $tc = new TaskCreation($this->container);
+ $s = new Subtask($this->container);
+ $p = new Project($this->container);
+
+ $this->assertEquals(1, $p->create(array('name' => 'test1')));
+ $this->assertEquals(1, $tc->create(array('title' => 'test 1', 'project_id' => 1)));
+
+ $this->assertEquals(1, $s->create(array('title' => 'subtask #1', 'task_id' => 1)));
+ $this->assertEquals(2, $s->create(array('title' => 'subtask #2', 'task_id' => 1)));
+ $this->assertEquals(3, $s->create(array('title' => 'subtask #3', 'task_id' => 1)));
+
+ $this->assertTrue($s->moveDown(1, 1));
+
+ $subtask = $s->getById(1);
+ $this->assertNotEmpty($subtask);
+ $this->assertEquals(2, $subtask['position']);
+
+ $subtask = $s->getById(2);
+ $this->assertNotEmpty($subtask);
+ $this->assertEquals(1, $subtask['position']);
+
+ $subtask = $s->getById(3);
+ $this->assertNotEmpty($subtask);
+ $this->assertEquals(3, $subtask['position']);
+
+ $this->assertFalse($s->moveDown(1, 3));
+ }
+
public function testDuplicate()
{
$tc = new TaskCreation($this->container);
@@ -53,5 +125,8 @@ class SubTaskTest extends Base
$this->assertEquals(0, $subtasks[0]['user_id']);
$this->assertEquals(0, $subtasks[1]['user_id']);
+
+ $this->assertEquals(1, $subtasks[0]['position']);
+ $this->assertEquals(2, $subtasks[1]['position']);
}
}
diff --git a/tests/units/SubtaskTimeTrackingTest.php b/tests/units/SubtaskTimeTrackingTest.php
index 90650e42..e15e60da 100644
--- a/tests/units/SubtaskTimeTrackingTest.php
+++ b/tests/units/SubtaskTimeTrackingTest.php
@@ -176,38 +176,35 @@ class SubtaskTimeTrackingTest extends Base
$this->assertEquals(7, $s->create(array('title' => 'subtask #7', 'task_id' => 2)));
$this->assertEquals(8, $s->create(array('title' => 'subtask #8', 'task_id' => 2)));
- // Create a couple of time slots
- $now = time();
-
// Slot start before and finish inside the calendar time range
- $this->container['db']->table(SubtaskTimeTracking::TABLE)->insert(array('user_id' => 1, 'subtask_id' => 1, 'start' => $now - 86400, 'end' => $now + 3600));
+ $this->container['db']->table(SubtaskTimeTracking::TABLE)->insert(array('user_id' => 1, 'subtask_id' => 1, 'start' => strtotime('-1 day'), 'end' => strtotime('+1 hour')));
// Slot start inside time range and finish after the time range
- $this->container['db']->table(SubtaskTimeTracking::TABLE)->insert(array('user_id' => 1, 'subtask_id' => 2, 'start' => $now + 3600, 'end' => $now + 2*86400));
+ $this->container['db']->table(SubtaskTimeTracking::TABLE)->insert(array('user_id' => 1, 'subtask_id' => 2, 'start' => strtotime('+1 hour'), 'end' => strtotime('+2 days')));
// Start before time range and finish inside time range
- $this->container['db']->table(SubtaskTimeTracking::TABLE)->insert(array('user_id' => 1, 'subtask_id' => 3, 'start' => $now - 86400, 'end' => $now + 1.5*86400));
+ $this->container['db']->table(SubtaskTimeTracking::TABLE)->insert(array('user_id' => 1, 'subtask_id' => 3, 'start' => strtotime('-1 day'), 'end' => strtotime('+1.5 days')));
// Start and finish inside time range
- $this->container['db']->table(SubtaskTimeTracking::TABLE)->insert(array('user_id' => 1, 'subtask_id' => 4, 'start' => $now + 3600, 'end' => $now + 2*3600));
+ $this->container['db']->table(SubtaskTimeTracking::TABLE)->insert(array('user_id' => 1, 'subtask_id' => 4, 'start' => strtotime('+1 hour'), 'end' => strtotime('+2 hours')));
// Start and finish after the time range
- $this->container['db']->table(SubtaskTimeTracking::TABLE)->insert(array('user_id' => 1, 'subtask_id' => 5, 'start' => $now + 2*86400, 'end' => $now + 3*86400));
+ $this->container['db']->table(SubtaskTimeTracking::TABLE)->insert(array('user_id' => 1, 'subtask_id' => 5, 'start' => strtotime('+2 days'), 'end' => strtotime('+3 days')));
// Start and finish before the time range
- $this->container['db']->table(SubtaskTimeTracking::TABLE)->insert(array('user_id' => 1, 'subtask_id' => 6, 'start' => $now - 2*86400, 'end' => $now - 86400));
+ $this->container['db']->table(SubtaskTimeTracking::TABLE)->insert(array('user_id' => 1, 'subtask_id' => 6, 'start' => strtotime('-2 days'), 'end' => strtotime('-1 day')));
// Start before time range and not finished
- $this->container['db']->table(SubtaskTimeTracking::TABLE)->insert(array('user_id' => 1, 'subtask_id' => 7, 'start' => $now - 86400));
+ $this->container['db']->table(SubtaskTimeTracking::TABLE)->insert(array('user_id' => 1, 'subtask_id' => 7, 'start' => strtotime('-1 day')));
// Start inside time range and not finish
- $this->container['db']->table(SubtaskTimeTracking::TABLE)->insert(array('user_id' => 1, 'subtask_id' => 8, 'start' => $now + 3200));
+ $this->container['db']->table(SubtaskTimeTracking::TABLE)->insert(array('user_id' => 1, 'subtask_id' => 8, 'start' => strtotime('+3200 seconds')));
$timesheet = $st->getUserTimesheet(1);
$this->assertNotEmpty($timesheet);
$this->assertCount(8, $timesheet);
- $events = $st->getUserCalendarEvents(1, date('Y-m-d', $now), date('Y-m-d', $now + 86400));
+ $events = $st->getUserCalendarEvents(1, date('Y-m-d'), date('Y-m-d', strtotime('+2 day')));
$this->assertNotEmpty($events);
$this->assertCount(6, $events);
$this->assertEquals(1, $events[0]['subtask_id']);
@@ -217,14 +214,14 @@ class SubtaskTimeTrackingTest extends Base
$this->assertEquals(7, $events[4]['subtask_id']);
$this->assertEquals(8, $events[5]['subtask_id']);
- $events = $st->getProjectCalendarEvents(1, date('Y-m-d', $now), date('Y-m-d', $now + 86400));
+ $events = $st->getProjectCalendarEvents(1, date('Y-m-d'), date('Y-m-d', strtotime('+2 days')));
$this->assertNotEmpty($events);
$this->assertCount(3, $events);
$this->assertEquals(1, $events[0]['subtask_id']);
$this->assertEquals(2, $events[1]['subtask_id']);
$this->assertEquals(3, $events[2]['subtask_id']);
- $events = $st->getProjectCalendarEvents(2, date('Y-m-d', $now), date('Y-m-d', $now + 86400));
+ $events = $st->getProjectCalendarEvents(2, date('Y-m-d'), date('Y-m-d', strtotime('+2 days')));
$this->assertNotEmpty($events);
$this->assertCount(3, $events);
$this->assertEquals(4, $events[0]['subtask_id']);
diff --git a/tests/units/TimetableTest.php b/tests/units/TimetableTest.php
new file mode 100644
index 00000000..2f38b534
--- /dev/null
+++ b/tests/units/TimetableTest.php
@@ -0,0 +1,253 @@
+<?php
+
+require_once __DIR__.'/Base.php';
+
+use Model\User;
+use Model\Timetable;
+use Model\TimetableDay;
+use Model\TimetableWeek;
+use Model\TimetableOff;
+use Model\TimetableExtra;
+
+class TimetableTest extends Base
+{
+ public function testCalculateWorkDays()
+ {
+ $w = new TimetableWeek($this->container);
+ $t = new Timetable($this->container);
+
+ $this->assertNotFalse($w->create(1, 1, '09:30', '12:00'));
+ $this->assertNotFalse($w->create(1, 1, '13:00', '17:00'));
+ $this->assertNotFalse($w->create(1, 2, '09:30', '12:00'));
+ $this->assertNotFalse($w->create(1, 2, '13:00', '17:00'));
+
+ $monday = new DateTime('next Monday');
+
+ $timetable = $t->calculate(1, $monday, new DateTime('next Monday + 6 days'));
+ $this->assertNotEmpty($timetable);
+ $this->assertCount(4, $timetable);
+
+ $this->assertEquals($monday->format('Y-m-d').' 09:30', $timetable[0][0]->format('Y-m-d H:i'));
+ $this->assertEquals($monday->format('Y-m-d').' 12:00', $timetable[0][1]->format('Y-m-d H:i'));
+ $this->assertEquals($monday->format('Y-m-d').' 13:00', $timetable[1][0]->format('Y-m-d H:i'));
+ $this->assertEquals($monday->format('Y-m-d').' 17:00', $timetable[1][1]->format('Y-m-d H:i'));
+
+ $this->assertEquals($monday->add(new DateInterval('P1D'))->format('Y-m-d').' 09:30', $timetable[2][0]->format('Y-m-d H:i'));
+ $this->assertEquals($monday->format('Y-m-d').' 12:00', $timetable[2][1]->format('Y-m-d H:i'));
+ $this->assertEquals($monday->format('Y-m-d').' 13:00', $timetable[3][0]->format('Y-m-d H:i'));
+ $this->assertEquals($monday->format('Y-m-d').' 17:00', $timetable[3][1]->format('Y-m-d H:i'));
+ }
+
+ public function testCalculateOverTime()
+ {
+ $d = new TimetableDay($this->container);
+ $w = new TimetableWeek($this->container);
+ $e = new TimetableExtra($this->container);
+ $t = new Timetable($this->container);
+
+ $monday = new DateTime('next Monday');
+ $tuesday = new DateTime('next Monday + 1 day');
+ $friday = new DateTime('next Monday + 4 days');
+
+ $this->assertNotFalse($d->create(1, '08:00', '12:00'));
+ $this->assertNotFalse($d->create(1, '14:00', '18:00'));
+
+ $this->assertNotFalse($w->create(1, 1, '09:30', '12:00'));
+ $this->assertNotFalse($w->create(1, 1, '13:00', '17:00'));
+ $this->assertNotFalse($w->create(1, 2, '09:30', '12:00'));
+ $this->assertNotFalse($w->create(1, 2, '13:00', '17:00'));
+
+ $this->assertNotFalse($e->create(1, $tuesday->format('Y-m-d'), 0, '17:00', '22:00'));
+ $this->assertNotFalse($e->create(1, $friday->format('Y-m-d'), 1));
+
+ $timetable = $t->calculate(1, $monday, new DateTime('next Monday + 6 days'));
+ $this->assertNotEmpty($timetable);
+ $this->assertCount(7, $timetable);
+
+ $this->assertEquals($monday->format('Y-m-d').' 09:30', $timetable[0][0]->format('Y-m-d H:i'));
+ $this->assertEquals($monday->format('Y-m-d').' 12:00', $timetable[0][1]->format('Y-m-d H:i'));
+ $this->assertEquals($monday->format('Y-m-d').' 13:00', $timetable[1][0]->format('Y-m-d H:i'));
+ $this->assertEquals($monday->format('Y-m-d').' 17:00', $timetable[1][1]->format('Y-m-d H:i'));
+
+ $this->assertEquals($tuesday->format('Y-m-d').' 09:30', $timetable[2][0]->format('Y-m-d H:i'));
+ $this->assertEquals($tuesday->format('Y-m-d').' 12:00', $timetable[2][1]->format('Y-m-d H:i'));
+ $this->assertEquals($tuesday->format('Y-m-d').' 13:00', $timetable[3][0]->format('Y-m-d H:i'));
+ $this->assertEquals($tuesday->format('Y-m-d').' 17:00', $timetable[3][1]->format('Y-m-d H:i'));
+
+ $this->assertEquals($tuesday->format('Y-m-d').' 17:00', $timetable[4][0]->format('Y-m-d H:i'));
+ $this->assertEquals($tuesday->format('Y-m-d').' 22:00', $timetable[4][1]->format('Y-m-d H:i'));
+
+ $this->assertEquals($friday->format('Y-m-d').' 08:00', $timetable[5][0]->format('Y-m-d H:i'));
+ $this->assertEquals($friday->format('Y-m-d').' 12:00', $timetable[5][1]->format('Y-m-d H:i'));
+
+ $this->assertEquals($friday->format('Y-m-d').' 14:00', $timetable[6][0]->format('Y-m-d H:i'));
+ $this->assertEquals($friday->format('Y-m-d').' 18:00', $timetable[6][1]->format('Y-m-d H:i'));
+ }
+
+ public function testCalculateTimeOff()
+ {
+ $d = new TimetableDay($this->container);
+ $w = new TimetableWeek($this->container);
+ $o = new TimetableOff($this->container);
+ $t = new Timetable($this->container);
+
+ $monday = new DateTime('next Monday');
+ $tuesday = new DateTime('next Monday + 1 day');
+ $friday = new DateTime('next Monday + 4 days');
+
+ $this->assertNotFalse($d->create(1, '08:00', '12:00'));
+ $this->assertNotFalse($d->create(1, '14:00', '18:00'));
+
+ $this->assertNotFalse($w->create(1, 1, '09:30', '12:00'));
+ $this->assertNotFalse($w->create(1, 1, '13:00', '17:00'));
+ $this->assertNotFalse($w->create(1, 2, '09:30', '12:00'));
+ $this->assertNotFalse($w->create(1, 2, '13:00', '17:00'));
+ $this->assertNotFalse($w->create(1, 5, '09:30', '12:00'));
+ $this->assertNotFalse($w->create(1, 5, '13:00', '17:00'));
+
+ $this->assertNotFalse($o->create(1, $tuesday->format('Y-m-d'), 0, '14:00', '15:00'));
+ $this->assertNotFalse($o->create(1, $monday->format('Y-m-d'), 1));
+
+ $timetable = $t->calculate(1, $monday, new DateTime('next Monday + 6 days'));
+ $this->assertNotEmpty($timetable);
+ $this->assertCount(5, $timetable);
+
+ $this->assertEquals($tuesday->format('Y-m-d').' 09:30', $timetable[0][0]->format('Y-m-d H:i'));
+ $this->assertEquals($tuesday->format('Y-m-d').' 12:00', $timetable[0][1]->format('Y-m-d H:i'));
+
+ $this->assertEquals($tuesday->format('Y-m-d').' 13:00', $timetable[1][0]->format('Y-m-d H:i'));
+ $this->assertEquals($tuesday->format('Y-m-d').' 14:00', $timetable[1][1]->format('Y-m-d H:i'));
+
+ $this->assertEquals($tuesday->format('Y-m-d').' 15:00', $timetable[2][0]->format('Y-m-d H:i'));
+ $this->assertEquals($tuesday->format('Y-m-d').' 17:00', $timetable[2][1]->format('Y-m-d H:i'));
+
+ $this->assertEquals($friday->format('Y-m-d').' 09:30', $timetable[3][0]->format('Y-m-d H:i'));
+ $this->assertEquals($friday->format('Y-m-d').' 12:00', $timetable[3][1]->format('Y-m-d H:i'));
+
+ $this->assertEquals($friday->format('Y-m-d').' 13:00', $timetable[4][0]->format('Y-m-d H:i'));
+ $this->assertEquals($friday->format('Y-m-d').' 17:00', $timetable[4][1]->format('Y-m-d H:i'));
+ }
+
+ public function testClosestTimeSlot()
+ {
+ $w = new TimetableWeek($this->container);
+ $t = new Timetable($this->container);
+
+ $this->assertNotFalse($w->create(1, 1, '09:30', '12:00'));
+ $this->assertNotFalse($w->create(1, 1, '13:00', '17:00'));
+ $this->assertNotFalse($w->create(1, 2, '09:30', '12:00'));
+ $this->assertNotFalse($w->create(1, 2, '13:00', '17:00'));
+
+ $monday = new DateTime('Monday');
+ $tuesday = new DateTime('Tuesday');
+
+ $timetable = $t->calculate(1, new DateTime('Monday'), new DateTime('Monday + 6 days'));
+ $this->assertNotEmpty($timetable);
+ $this->assertCount(4, $timetable);
+
+ // Start to work before timetable
+ $date = new DateTime('Monday');
+ $date->setTime(5, 02);
+
+ $slot = $t->findClosestTimeSlot($date, $timetable);
+ $this->assertNotEmpty($slot);
+ $this->assertEquals($monday->format('Y-m-d').' 09:30', $slot[0]->format('Y-m-d H:i'));
+ $this->assertEquals($monday->format('Y-m-d').' 12:00', $slot[1]->format('Y-m-d H:i'));
+
+ // Start to work at the end of the timeslot
+ $date = new DateTime('Monday');
+ $date->setTime(12, 02);
+
+ $slot = $t->findClosestTimeSlot($date, $timetable);
+ $this->assertNotEmpty($slot);
+ $this->assertEquals($monday->format('Y-m-d').' 09:30', $slot[0]->format('Y-m-d H:i'));
+ $this->assertEquals($monday->format('Y-m-d').' 12:00', $slot[1]->format('Y-m-d H:i'));
+
+ // Start to work at lunch time
+ $date = new DateTime('Monday');
+ $date->setTime(12, 32);
+
+ $slot = $t->findClosestTimeSlot($date, $timetable);
+ $this->assertNotEmpty($slot);
+ $this->assertEquals($monday->format('Y-m-d').' 13:00', $slot[0]->format('Y-m-d H:i'));
+ $this->assertEquals($monday->format('Y-m-d').' 17:00', $slot[1]->format('Y-m-d H:i'));
+
+ // Start to work early in the morning
+ $date = new DateTime('Tuesday');
+ $date->setTime(8, 02);
+
+ $slot = $t->findClosestTimeSlot($date, $timetable);
+ $this->assertNotEmpty($slot);
+ $this->assertEquals($tuesday->format('Y-m-d').' 09:30', $slot[0]->format('Y-m-d H:i'));
+ $this->assertEquals($tuesday->format('Y-m-d').' 12:00', $slot[1]->format('Y-m-d H:i'));
+ }
+
+ public function testCalculateDuration()
+ {
+ $w = new TimetableWeek($this->container);
+ $t = new Timetable($this->container);
+
+ $this->assertNotFalse($w->create(1, 1, '09:30', '12:00'));
+ $this->assertNotFalse($w->create(1, 1, '13:00', '17:00'));
+ $this->assertNotFalse($w->create(1, 2, '09:30', '12:00'));
+ $this->assertNotFalse($w->create(1, 2, '13:00', '17:00'));
+
+ // Different day
+ $start = new DateTime('Monday');
+ $start->setTime(16, 02);
+
+ $end = new DateTime('Tuesday');
+ $end->setTime(10, 03);
+
+ $this->assertEquals(1.5, $t->calculateEffectiveDuration(1, $start, $end));
+
+ // Same time slot
+ $start = new DateTime('Monday');
+ $start->setTime(16, 02);
+
+ $end = new DateTime('Monday');
+ $end->setTime(17, 03);
+
+ $this->assertEquals(1, $t->calculateEffectiveDuration(1, $start, $end));
+
+ // Intermediate time slot
+ $start = new DateTime('Monday');
+ $start->setTime(10, 02);
+
+ $end = new DateTime('Tuesday');
+ $end->setTime(16, 03);
+
+ $this->assertEquals(11.5, $t->calculateEffectiveDuration(1, $start, $end));
+
+ // Different day
+ $start = new DateTime('Monday');
+ $start->setTime(9, 02);
+
+ $end = new DateTime('Tuesday');
+ $end->setTime(10, 03);
+
+ $this->assertEquals(7, $t->calculateEffectiveDuration(1, $start, $end));
+
+ // Start before first time slot
+ $start = new DateTime('Monday');
+ $start->setTime(5, 32);
+
+ $end = new DateTime('Tuesday');
+ $end->setTime(11, 17);
+
+ $this->assertEquals(8.25, $t->calculateEffectiveDuration(1, $start, $end));
+ }
+
+ public function testCalculateDurationWithEmptyTimetable()
+ {
+ $t = new Timetable($this->container);
+
+ $start = new DateTime('Monday');
+ $start->setTime(16, 02);
+
+ $end = new DateTime('Monday');
+ $end->setTime(17, 03);
+
+ $this->assertEquals(1, $t->calculateEffectiveDuration(1, $start, $end));
+ }
+}