diff options
Diffstat (limited to 'tests/units/Core')
30 files changed, 2907 insertions, 139 deletions
diff --git a/tests/units/Core/Action/ActionManagerTest.php b/tests/units/Core/Action/ActionManagerTest.php new file mode 100644 index 00000000..aae5bd2d --- /dev/null +++ b/tests/units/Core/Action/ActionManagerTest.php @@ -0,0 +1,196 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Action\ActionManager; +use Kanboard\Action\TaskAssignColorColumn; +use Kanboard\Action\TaskClose; +use Kanboard\Action\TaskCloseColumn; +use Kanboard\Action\TaskUpdateStartDate; +use Kanboard\Model\Action; +use Kanboard\Model\Task; +use Kanboard\Model\Project; +use Kanboard\Model\ProjectUserRole; +use Kanboard\Core\Security\Role; + +class ActionManagerTest extends Base +{ + public function testRegister() + { + $actionManager = new ActionManager($this->container); + $actionTaskClose = new TaskClose($this->container); + + $actionManager->register($actionTaskClose); + $this->assertInstanceOf(get_class($actionTaskClose), $actionManager->getAction($actionTaskClose->getName())); + } + + public function testGetActionNotFound() + { + $this->setExpectedException('RuntimeException', 'Automatic Action Not Found: foobar'); + $actionManager = new ActionManager($this->container); + $actionManager->getAction('foobar'); + } + + public function testGetAvailableActions() + { + $actionManager = new ActionManager($this->container); + $actionTaskClose1 = new TaskCloseColumn($this->container); + $actionTaskClose2 = new TaskCloseColumn($this->container); + $actionTaskUpdateStartDate = new TaskUpdateStartDate($this->container); + + $actionManager + ->register($actionTaskClose1) + ->register($actionTaskClose2) + ->register($actionTaskUpdateStartDate); + + $actions = $actionManager->getAvailableActions(); + $this->assertCount(2, $actions); + $this->assertArrayHasKey($actionTaskClose1->getName(), $actions); + $this->assertArrayHasKey($actionTaskUpdateStartDate->getName(), $actions); + $this->assertNotEmpty($actions[$actionTaskClose1->getName()]); + $this->assertNotEmpty($actions[$actionTaskUpdateStartDate->getName()]); + } + + public function testGetAvailableParameters() + { + $actionManager = new ActionManager($this->container); + + $actionManager + ->register(new TaskCloseColumn($this->container)) + ->register(new TaskUpdateStartDate($this->container)); + + $params = $actionManager->getAvailableParameters(array( + array('action_name' => '\Kanboard\Action\TaskCloseColumn'), + array('action_name' => '\Kanboard\Action\TaskUpdateStartDate'), + )); + + $this->assertCount(2, $params); + $this->assertArrayHasKey('column_id', $params['\Kanboard\Action\TaskCloseColumn']); + $this->assertArrayHasKey('column_id', $params['\Kanboard\Action\TaskUpdateStartDate']); + $this->assertNotEmpty($params['\Kanboard\Action\TaskCloseColumn']['column_id']); + $this->assertNotEmpty($params['\Kanboard\Action\TaskUpdateStartDate']['column_id']); + } + + public function testGetCompatibleEvents() + { + $actionTaskAssignColorColumn = new TaskAssignColorColumn($this->container); + $actionManager = new ActionManager($this->container); + $actionManager->register($actionTaskAssignColorColumn); + + $events = $actionManager->getCompatibleEvents('\\'.get_class($actionTaskAssignColorColumn)); + $this->assertCount(2, $events); + $this->assertArrayHasKey(Task::EVENT_CREATE, $events); + $this->assertArrayHasKey(Task::EVENT_MOVE_COLUMN, $events); + $this->assertNotEmpty($events[Task::EVENT_CREATE]); + $this->assertNotEmpty($events[Task::EVENT_MOVE_COLUMN]); + } + + public function testAttachEventsWithoutUserSession() + { + $projectModel = new Project($this->container); + $actionModel = new Action($this->container); + $actionTaskAssignColorColumn = new TaskAssignColorColumn($this->container); + $actionManager = new ActionManager($this->container); + $actionManager->register($actionTaskAssignColorColumn); + + $actions = $actionManager->getAvailableActions(); + + $actionManager->attachEvents(); + $this->assertEmpty($this->container['dispatcher']->getListeners()); + + $this->assertEquals(1, $projectModel->create(array('name' =>'test'))); + $this->assertEquals(1, $actionModel->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_CREATE, + 'action_name' => key($actions), + 'params' => array('column_id' => 1, 'color_id' => 'red'), + ))); + + $actionManager->attachEvents(); + $listeners = $this->container['dispatcher']->getListeners(Task::EVENT_CREATE); + $this->assertCount(1, $listeners); + $this->assertInstanceOf(get_class($actionTaskAssignColorColumn), $listeners[0][0]); + + $this->assertEquals(1, $listeners[0][0]->getProjectId()); + } + + public function testAttachEventsWithLoggedUser() + { + $this->container['sessionStorage']->user = array('id' => 1); + + $projectModel = new Project($this->container); + $projectUserRoleModel = new ProjectUserRole($this->container); + $actionModel = new Action($this->container); + $actionTaskAssignColorColumn = new TaskAssignColorColumn($this->container); + $actionManager = new ActionManager($this->container); + $actionManager->register($actionTaskAssignColorColumn); + + $actions = $actionManager->getAvailableActions(); + + $this->assertEquals(1, $projectModel->create(array('name' =>'test1'))); + $this->assertEquals(2, $projectModel->create(array('name' =>'test2'))); + + $this->assertTrue($projectUserRoleModel->addUser(2, 1, Role::PROJECT_MEMBER)); + + $this->assertEquals(1, $actionModel->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_CREATE, + 'action_name' => key($actions), + 'params' => array('column_id' => 1, 'color_id' => 'red'), + ))); + + $this->assertEquals(2, $actionModel->create(array( + 'project_id' => 2, + 'event_name' => Task::EVENT_MOVE_COLUMN, + 'action_name' => key($actions), + 'params' => array('column_id' => 1, 'color_id' => 'red'), + ))); + + $actionManager->attachEvents(); + + $listeners = $this->container['dispatcher']->getListeners(Task::EVENT_MOVE_COLUMN); + $this->assertCount(1, $listeners); + $this->assertInstanceOf(get_class($actionTaskAssignColorColumn), $listeners[0][0]); + + $this->assertEquals(2, $listeners[0][0]->getProjectId()); + } + + public function testThatEachListenerAreDifferentInstance() + { + $projectModel = new Project($this->container); + $projectUserRoleModel = new ProjectUserRole($this->container); + $actionModel = new Action($this->container); + $actionTaskAssignColorColumn = new TaskAssignColorColumn($this->container); + $actionManager = new ActionManager($this->container); + $actionManager->register($actionTaskAssignColorColumn); + + $this->assertEquals(1, $projectModel->create(array('name' =>'test1'))); + $actions = $actionManager->getAvailableActions(); + + $this->assertEquals(1, $actionModel->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_MOVE_COLUMN, + 'action_name' => key($actions), + 'params' => array('column_id' => 2, 'color_id' => 'green'), + ))); + + $this->assertEquals(2, $actionModel->create(array( + 'project_id' => 1, + 'event_name' => Task::EVENT_MOVE_COLUMN, + 'action_name' => key($actions), + 'params' => array('column_id' => 1, 'color_id' => 'red'), + ))); + + $actionManager->attachEvents(); + + $listeners = $this->container['dispatcher']->getListeners(Task::EVENT_MOVE_COLUMN); + $this->assertCount(2, $listeners); + $this->assertFalse($listeners[0][0] === $listeners[1][0]); + + $this->assertEquals(2, $listeners[0][0]->getParam('column_id')); + $this->assertEquals('green', $listeners[0][0]->getParam('color_id')); + + $this->assertEquals(1, $listeners[1][0]->getParam('column_id')); + $this->assertEquals('red', $listeners[1][0]->getParam('color_id')); + } +} diff --git a/tests/units/Core/CsvTest.php b/tests/units/Core/CsvTest.php index 71542c20..da0be4a3 100644 --- a/tests/units/Core/CsvTest.php +++ b/tests/units/Core/CsvTest.php @@ -14,9 +14,43 @@ class CsvTest extends Base $this->assertEquals(1, Csv::getBooleanValue('TRUE')); $this->assertEquals(1, Csv::getBooleanValue('true')); $this->assertEquals(1, Csv::getBooleanValue('T')); + $this->assertEquals(1, Csv::getBooleanValue('Y')); + $this->assertEquals(1, Csv::getBooleanValue('y')); + $this->assertEquals(1, Csv::getBooleanValue('yes')); + $this->assertEquals(1, Csv::getBooleanValue('Yes')); $this->assertEquals(0, Csv::getBooleanValue('0')); $this->assertEquals(0, Csv::getBooleanValue('123')); $this->assertEquals(0, Csv::getBooleanValue('anything')); } + + public function testGetEnclosures() + { + $this->assertCount(3, Csv::getEnclosures()); + $this->assertCount(4, Csv::getDelimiters()); + } + + public function testReadWrite() + { + $filename = tempnam(sys_get_temp_dir(), 'UT'); + $rows = array( + array('Column A', 'Column B'), + array('value a', 'value b'), + ); + + $csv = new Csv; + $csv->write($filename, $rows); + $csv->setColumnMapping(array('A', 'B', 'C')); + $csv->read($filename, array($this, 'readRow')); + + unlink($filename); + + $this->expectOutputString('"Column A","Column B"'."\n".'"value a","value b"'."\n", $csv->output($rows)); + } + + public function readRow(array $row, $line) + { + $this->assertEquals(array('value a', 'value b', ''), $row); + $this->assertEquals(1, $line); + } } diff --git a/tests/units/Core/DateParserTest.php b/tests/units/Core/DateParserTest.php index 0d345784..dc3366b3 100644 --- a/tests/units/Core/DateParserTest.php +++ b/tests/units/Core/DateParserTest.php @@ -6,79 +6,167 @@ use Kanboard\Core\DateParser; class DateParserTest extends Base { + public function testGetTimeFormats() + { + $dateParser = new DateParser($this->container); + $this->assertCount(2, $dateParser->getTimeFormats()); + $this->assertContains('H:i', $dateParser->getTimeFormats()); + $this->assertContains('g:i a', $dateParser->getTimeFormats()); + } + + public function testGetDateFormats() + { + $dateParser = new DateParser($this->container); + $this->assertCount(4, $dateParser->getDateFormats()); + $this->assertCount(6, $dateParser->getDateFormats(true)); + $this->assertContains('d/m/Y', $dateParser->getDateFormats()); + $this->assertNotContains('Y-m-d', $dateParser->getDateFormats()); + $this->assertContains('Y-m-d', $dateParser->getDateFormats(true)); + } + + public function testGetDateTimeFormats() + { + $dateParser = new DateParser($this->container); + $this->assertCount(8, $dateParser->getDateTimeFormats()); + $this->assertCount(12, $dateParser->getDateTimeFormats(true)); + $this->assertContains('d/m/Y H:i', $dateParser->getDateTimeFormats()); + $this->assertNotContains('Y-m-d H:i', $dateParser->getDateTimeFormats()); + $this->assertContains('Y-m-d g:i a', $dateParser->getDateTimeFormats(true)); + } + + public function testGetAllDateFormats() + { + $dateParser = new DateParser($this->container); + $this->assertCount(12, $dateParser->getAllDateFormats()); + $this->assertCount(18, $dateParser->getAllDateFormats(true)); + $this->assertContains('d/m/Y', $dateParser->getAllDateFormats()); + $this->assertContains('d/m/Y H:i', $dateParser->getAllDateFormats()); + $this->assertNotContains('Y-m-d H:i', $dateParser->getAllDateFormats()); + $this->assertContains('Y-m-d g:i a', $dateParser->getAllDateFormats(true)); + $this->assertContains('Y-m-d', $dateParser->getAllDateFormats(true)); + } + + public function testGetAllAvailableFormats() + { + $dateParser = new DateParser($this->container); + + $formats = $dateParser->getAvailableFormats($dateParser->getDateFormats()); + $this->assertArrayHasKey('d/m/Y', $formats); + $this->assertContains(date('d/m/Y'), $formats); + + $formats = $dateParser->getAvailableFormats($dateParser->getDateTimeFormats()); + $this->assertArrayHasKey('d/m/Y H:i', $formats); + $this->assertContains(date('d/m/Y H:i'), $formats); + + $formats = $dateParser->getAvailableFormats($dateParser->getAllDateFormats()); + $this->assertArrayHasKey('d/m/Y', $formats); + $this->assertContains(date('d/m/Y'), $formats); + $this->assertArrayHasKey('d/m/Y H:i', $formats); + $this->assertContains(date('d/m/Y H:i'), $formats); + } + + public function testGetTimestamp() + { + $dateParser = new DateParser($this->container); + + $this->assertEquals(1393995600, $dateParser->getTimestamp(1393995600)); + $this->assertEquals('2014-03-05', date('Y-m-d', $dateParser->getTimestamp('2014-03-05'))); + $this->assertEquals('2014-03-05', date('Y-m-d', $dateParser->getTimestamp('2014_03_05'))); + $this->assertEquals('2014-03-05', date('Y-m-d', $dateParser->getTimestamp('03/05/2014'))); + $this->assertEquals('2014-03-25 17:18', date('Y-m-d H:i', $dateParser->getTimestamp('03/25/2014 5:18 pm'))); + $this->assertEquals('2014-03-25 05:18', date('Y-m-d H:i', $dateParser->getTimestamp('03/25/2014 5:18 am'))); + $this->assertEquals('2014-03-25 17:18', date('Y-m-d H:i', $dateParser->getTimestamp('03/25/2014 5:18pm'))); + $this->assertEquals('2014-03-25 23:14', date('Y-m-d H:i', $dateParser->getTimestamp('03/25/2014 23:14'))); + $this->assertEquals('2014-03-29 23:14', date('Y-m-d H:i', $dateParser->getTimestamp('2014_03_29 23:14'))); + $this->assertEquals('2014-03-29 23:14', date('Y-m-d H:i', $dateParser->getTimestamp('2014-03-29 23:14'))); + } + public function testDateRange() { - $d = new DateParser($this->container); + $dateParser = 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'))); + $this->assertTrue($dateParser->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($dateParser->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 testGetHours() + { + $dateParser = new DateParser($this->container); + + $this->assertEquals(1, $dateParser->getHours(new DateTime('2015-03-14 15:00:00'), new DateTime('2015-03-14 16:00:00'))); + $this->assertEquals(2.5, $dateParser->getHours(new DateTime('2015-03-14 15:00:00'), new DateTime('2015-03-14 17:30:00'))); + $this->assertEquals(2.75, $dateParser->getHours(new DateTime('2015-03-14 15:00:00'), new DateTime('2015-03-14 17:45:00'))); + $this->assertEquals(3, $dateParser->getHours(new DateTime('2015-03-14 14:57:00'), new DateTime('2015-03-14 17:58:00'))); + $this->assertEquals(3, $dateParser->getHours(new DateTime('2015-03-14 14:57:00'), new DateTime('2015-03-14 11:58: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')))); + $dateParser = new DateParser($this->container); + $this->assertEquals('16:30', date('H:i', $dateParser->getRoundedSeconds(strtotime('16:28')))); + $this->assertEquals('16:00', date('H:i', $dateParser->getRoundedSeconds(strtotime('16:02')))); + $this->assertEquals('16:15', date('H:i', $dateParser->getRoundedSeconds(strtotime('16:14')))); + $this->assertEquals('17:00', date('H:i', $dateParser->getRoundedSeconds(strtotime('16:58')))); } - public function testGetHours() + public function testGetIsoDate() { - $d = new DateParser($this->container); + $dateParser = new DateParser($this->container); + + $this->assertEquals('2016-02-06', $dateParser->getIsoDate(1454786217)); + $this->assertEquals('2014-03-05', $dateParser->getIsoDate('2014-03-05')); + $this->assertEquals('2014-03-05', $dateParser->getIsoDate('2014_03_05')); + $this->assertEquals('2014-03-05', $dateParser->getIsoDate('03/05/2014')); + $this->assertEquals('2014-03-25', $dateParser->getIsoDate('03/25/2014 5:18 pm')); + $this->assertEquals('2014-03-25', $dateParser->getIsoDate('03/25/2014 5:18 am')); + $this->assertEquals('2014-03-25', $dateParser->getIsoDate('03/25/2014 5:18pm')); + $this->assertEquals('2014-03-25', $dateParser->getIsoDate('03/25/2014 23:14')); + $this->assertEquals('2014-03-29', $dateParser->getIsoDate('2014_03_29 23:14')); + $this->assertEquals('2014-03-29', $dateParser->getIsoDate('2014-03-29 23:14')); + } - $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 testGetTimestampFromIsoFormat() + { + $dateParser = new DateParser($this->container); + $this->assertEquals('2014-03-05 00:00', date('Y-m-d H:i', $dateParser->getTimestampFromIsoFormat('2014-03-05'))); + $this->assertEquals(date('Y-m-d 00:00', strtotime('+2 days')), date('Y-m-d H:i', $dateParser->getTimestampFromIsoFormat(strtotime('+2 days')))); } - public function testValidDate() + public function testRemoveTimeFromTimestamp() { - $d = new DateParser($this->container); - - $this->assertEquals('2014-03-05', date('Y-m-d', $d->getValidDate('2014-03-05', 'Y-m-d'))); - $this->assertEquals('2014-03-05', date('Y-m-d', $d->getValidDate('2014_03_05', 'Y_m_d'))); - $this->assertEquals('2014-03-05', date('Y-m-d', $d->getValidDate('05/03/2014', 'd/m/Y'))); - $this->assertEquals('2014-03-05', date('Y-m-d', $d->getValidDate('03/05/2014', 'm/d/Y'))); - $this->assertEquals('2014-03-05', date('Y-m-d', $d->getValidDate('3/5/2014', 'm/d/Y'))); - $this->assertEquals('2014-03-05', date('Y-m-d', $d->getValidDate('5/3/2014', 'd/m/Y'))); - $this->assertEquals('2014-03-05', date('Y-m-d', $d->getValidDate('5/3/14', 'd/m/y'))); - $this->assertEquals(0, $d->getValidDate('5/3/14', 'd/m/Y')); - $this->assertEquals(0, $d->getValidDate('5-3-2014', 'd/m/Y')); + $dateParser = new DateParser($this->container); + $this->assertEquals('2016-02-06 00:00', date('Y-m-d H:i', $dateParser->removeTimeFromTimestamp(1454786217))); } - public function testGetTimestamp() + public function testFormat() { - $d = new DateParser($this->container); - - $this->assertEquals('2014-03-05', date('Y-m-d', $d->getTimestamp('2014-03-05'))); - $this->assertEquals('2014-03-05', date('Y-m-d', $d->getTimestamp('2014_03_05'))); - $this->assertEquals('2014-03-05', date('Y-m-d', $d->getTimestamp('03/05/2014'))); - $this->assertEquals('2014-03-25 17:18', date('Y-m-d H:i', $d->getTimestamp('03/25/2014 5:18 pm'))); - $this->assertEquals('2014-03-25 05:18', date('Y-m-d H:i', $d->getTimestamp('03/25/2014 5:18 am'))); - $this->assertEquals('2014-03-25 05:18', date('Y-m-d H:i', $d->getTimestamp('03/25/2014 5:18am'))); - $this->assertEquals('2014-03-25 23:14', date('Y-m-d H:i', $d->getTimestamp('03/25/2014 23:14'))); - $this->assertEquals('2014-03-29 23:14', date('Y-m-d H:i', $d->getTimestamp('2014_03_29 23:14'))); - $this->assertEquals('2014-03-29 23:14', date('Y-m-d H:i', $d->getTimestamp('2014-03-29 23:14'))); + $dateParser = new DateParser($this->container); + $values['date'] = '1454787006'; + + $this->assertEquals(array('date' => '06/02/2016'), $dateParser->format($values, array('date'), 'd/m/Y')); + $this->assertEquals(array('date' => '02/06/2016 7:30 pm'), $dateParser->format($values, array('date'), 'm/d/Y g:i a')); } public function testConvert() { - $d = new DateParser($this->container); - + $dateParser = new DateParser($this->container); $values = array( 'date_due' => '2015-01-25', - 'date_started' => '2015_01_25', + 'date_started' => '2015-01-25 17:25', ); - $d->convert($values, array('date_due', 'date_started')); + $this->assertEquals( + array('date_due' => 1422144000, 'date_started' => 1422144000), + $dateParser->convert($values, array('date_due', 'date_started')) + ); - $this->assertEquals(mktime(0, 0, 0, 1, 25, 2015), $values['date_due']); - $this->assertEquals('2015-01-25', date('Y-m-d', $values['date_due'])); + $values = array( + 'date_started' => '2015-01-25 17:25', + ); - $this->assertEquals(mktime(0, 0, 0, 1, 25, 2015), $values['date_started']); - $this->assertEquals('2015-01-25', date('Y-m-d', $values['date_started'])); + $this->assertEquals( + array('date_started' => 1422206700), + $dateParser->convert($values, array('date_due', 'date_started'), true) + ); } } diff --git a/tests/units/Core/Event/EventManagerTest.php b/tests/units/Core/Event/EventManagerTest.php new file mode 100644 index 00000000..974fde62 --- /dev/null +++ b/tests/units/Core/Event/EventManagerTest.php @@ -0,0 +1,18 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Event\EventManager; + +class EventManagerTest extends Base +{ + public function testAddEvent() + { + $eventManager = new EventManager; + $eventManager->register('my.event', 'My Event'); + + $events = $eventManager->getAll(); + $this->assertArrayHasKey('my.event', $events); + $this->assertEquals('My Event', $events['my.event']); + } +} diff --git a/tests/units/Core/ExternalLink/ExternalLinkManagerTest.php b/tests/units/Core/ExternalLink/ExternalLinkManagerTest.php new file mode 100644 index 00000000..d284a80b --- /dev/null +++ b/tests/units/Core/ExternalLink/ExternalLinkManagerTest.php @@ -0,0 +1,120 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\ExternalLink\ExternalLinkManager; +use Kanboard\ExternalLink\WebLinkProvider; +use Kanboard\ExternalLink\AttachmentLinkProvider; + +class ExternalLinkManagerTest extends Base +{ + public function testRegister() + { + $externalLinkManager = new ExternalLinkManager($this->container); + $webLinkProvider = new WebLinkProvider($this->container); + $attachmentLinkProvider = new AttachmentLinkProvider($this->container); + + $externalLinkManager->register($webLinkProvider); + $externalLinkManager->register($attachmentLinkProvider); + + $this->assertInstanceOf(get_class($webLinkProvider), $externalLinkManager->getProvider($webLinkProvider->getType())); + $this->assertInstanceOf(get_class($attachmentLinkProvider), $externalLinkManager->getProvider($attachmentLinkProvider->getType())); + } + + public function testGetProviderNotFound() + { + $externalLinkManager = new ExternalLinkManager($this->container); + + $this->setExpectedException('\Kanboard\Core\ExternalLink\ExternalLinkProviderNotFound'); + $externalLinkManager->getProvider('not found'); + } + + public function testGetTypes() + { + $externalLinkManager = new ExternalLinkManager($this->container); + $webLinkProvider = new WebLinkProvider($this->container); + $attachmentLinkProvider = new AttachmentLinkProvider($this->container); + + $this->assertEquals(array(ExternalLinkManager::TYPE_AUTO => 'Auto'), $externalLinkManager->getTypes()); + + $externalLinkManager->register($webLinkProvider); + $externalLinkManager->register($attachmentLinkProvider); + + $this->assertEquals( + array(ExternalLinkManager::TYPE_AUTO => 'Auto', 'attachment' => 'Attachment', 'weblink' => 'Web Link'), + $externalLinkManager->getTypes() + ); + } + + public function testGetDependencyLabel() + { + $externalLinkManager = new ExternalLinkManager($this->container); + $webLinkProvider = new WebLinkProvider($this->container); + $attachmentLinkProvider = new AttachmentLinkProvider($this->container); + + $externalLinkManager->register($webLinkProvider); + $externalLinkManager->register($attachmentLinkProvider); + + $this->assertSame('Related', $externalLinkManager->getDependencyLabel($webLinkProvider->getType(), 'related')); + $this->assertSame('custom', $externalLinkManager->getDependencyLabel($webLinkProvider->getType(), 'custom')); + } + + public function testFindProviderNotFound() + { + $externalLinkManager = new ExternalLinkManager($this->container); + $webLinkProvider = new WebLinkProvider($this->container); + $attachmentLinkProvider = new AttachmentLinkProvider($this->container); + + $externalLinkManager->register($webLinkProvider); + $externalLinkManager->register($attachmentLinkProvider); + + $this->setExpectedException('\Kanboard\Core\ExternalLink\ExternalLinkProviderNotFound'); + $externalLinkManager->find(); + } + + public function testFindProvider() + { + $externalLinkManager = new ExternalLinkManager($this->container); + $webLinkProvider = new WebLinkProvider($this->container); + $attachmentLinkProvider = new AttachmentLinkProvider($this->container); + + $externalLinkManager->register($webLinkProvider); + $externalLinkManager->register($attachmentLinkProvider); + + $externalLinkManager->setUserInput(array('text' => 'https://google.com/', 'type' => ExternalLinkManager::TYPE_AUTO)); + $this->assertSame($webLinkProvider, $externalLinkManager->find()); + + $externalLinkManager->setUserInput(array('text' => 'https://google.com/file.pdf', 'type' => ExternalLinkManager::TYPE_AUTO)); + $this->assertSame($attachmentLinkProvider, $externalLinkManager->find()); + } + + public function testFindProviderWithSelectedType() + { + $externalLinkManager = new ExternalLinkManager($this->container); + $webLinkProvider = new WebLinkProvider($this->container); + $attachmentLinkProvider = new AttachmentLinkProvider($this->container); + + $externalLinkManager->register($webLinkProvider); + $externalLinkManager->register($attachmentLinkProvider); + + $externalLinkManager->setUserInput(array('text' => 'https://google.com/', 'type' => $webLinkProvider->getType())); + $this->assertSame($webLinkProvider, $externalLinkManager->find()); + + $externalLinkManager->setUserInput(array('text' => 'https://google.com/file.pdf', 'type' => $attachmentLinkProvider->getType())); + $this->assertSame($attachmentLinkProvider, $externalLinkManager->find()); + } + + public function testFindProviderWithSelectedTypeNotFound() + { + $externalLinkManager = new ExternalLinkManager($this->container); + $webLinkProvider = new WebLinkProvider($this->container); + $attachmentLinkProvider = new AttachmentLinkProvider($this->container); + + $externalLinkManager->register($webLinkProvider); + $externalLinkManager->register($attachmentLinkProvider); + + $this->setExpectedException('\Kanboard\Core\ExternalLink\ExternalLinkProviderNotFound'); + $externalLinkManager->setUserInput(array('text' => 'https://google.com/', 'type' => 'not found')); + $externalLinkManager->find(); + } +} diff --git a/tests/units/Core/Group/GroupManagerTest.php b/tests/units/Core/Group/GroupManagerTest.php new file mode 100644 index 00000000..faf5501f --- /dev/null +++ b/tests/units/Core/Group/GroupManagerTest.php @@ -0,0 +1,42 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Model\Group; +use Kanboard\Core\Group\GroupManager; +use Kanboard\Group\DatabaseBackendGroupProvider; + +class GroupManagerTest extends Base +{ + public function testFind() + { + $groupModel = new Group($this->container); + $groupManager = new GroupManager; + + $this->assertEquals(1, $groupModel->create('Group 1')); + $this->assertEquals(2, $groupModel->create('Group 2')); + + $this->assertEmpty($groupManager->find('group 1')); + + $groupManager->register(new DatabaseBackendGroupProvider($this->container)); + $groupManager->register(new DatabaseBackendGroupProvider($this->container)); + + $groups = $groupManager->find('group 1'); + $this->assertCount(1, $groups); + $this->assertInstanceOf('Kanboard\Group\DatabaseGroupProvider', $groups[0]); + $this->assertEquals('Group 1', $groups[0]->getName()); + $this->assertEquals('', $groups[0]->getExternalId()); + $this->assertEquals(1, $groups[0]->getInternalId()); + + $groups = $groupManager->find('grou'); + $this->assertCount(2, $groups); + $this->assertInstanceOf('Kanboard\Group\DatabaseGroupProvider', $groups[0]); + $this->assertInstanceOf('Kanboard\Group\DatabaseGroupProvider', $groups[1]); + $this->assertEquals('Group 1', $groups[0]->getName()); + $this->assertEquals('Group 2', $groups[1]->getName()); + $this->assertEquals('', $groups[0]->getExternalId()); + $this->assertEquals('', $groups[1]->getExternalId()); + $this->assertEquals(1, $groups[0]->getInternalId()); + $this->assertEquals(2, $groups[1]->getInternalId()); + } +} diff --git a/tests/units/Core/OAuth2Test.php b/tests/units/Core/Http/OAuth2Test.php index d5713608..c68ae116 100644 --- a/tests/units/Core/OAuth2Test.php +++ b/tests/units/Core/Http/OAuth2Test.php @@ -1,8 +1,8 @@ <?php -require_once __DIR__.'/../Base.php'; +require_once __DIR__.'/../../Base.php'; -use Kanboard\Core\OAuth2; +use Kanboard\Core\Http\OAuth2; class OAuth2Test extends Base { @@ -27,17 +27,27 @@ class OAuth2Test extends Base public function testAccessToken() { + $params = array( + 'code' => 'something', + 'client_id' => 'A', + 'client_secret' => 'B', + 'redirect_uri' => 'C', + 'grant_type' => 'authorization_code', + ); + + $response = json_encode(array( + 'token_type' => 'bearer', + 'access_token' => 'plop', + )); + + $this->container['httpClient'] + ->expects($this->once()) + ->method('postForm') + ->with('E', $params, array('Accept: application/json')) + ->will($this->returnValue($response)); + $oauth = new OAuth2($this->container); $oauth->createService('A', 'B', 'C', 'D', 'E', array('f', 'g')); $oauth->getAccessToken('something'); - - $data = $this->container['httpClient']->getData(); - $this->assertEquals('something', $data['code']); - $this->assertEquals('A', $data['client_id']); - $this->assertEquals('B', $data['client_secret']); - $this->assertEquals('C', $data['redirect_uri']); - $this->assertEquals('authorization_code', $data['grant_type']); - - $this->assertEquals('E', $this->container['httpClient']->getUrl()); } } diff --git a/tests/units/Core/Http/RememberMeCookieTest.php b/tests/units/Core/Http/RememberMeCookieTest.php new file mode 100644 index 00000000..ae5606ac --- /dev/null +++ b/tests/units/Core/Http/RememberMeCookieTest.php @@ -0,0 +1,108 @@ +<?php + +namespace Kanboard\Core\Http; + +require_once __DIR__.'/../../Base.php'; + +function setcookie($name, $value = "", $expire = 0, $path = "", $domain = "", $secure = false, $httponly = false) +{ + return RememberMeCookieTest::$functions->setcookie($name, $value, $expire, $path, $domain, $secure, $httponly); +} + +class RememberMeCookieTest extends \Base +{ + public static $functions; + + public function setUp() + { + parent::setup(); + + self::$functions = $this + ->getMockBuilder('stdClass') + ->setMethods(array( + 'setcookie', + )) + ->getMock(); + } + + public function tearDown() + { + parent::tearDown(); + self::$functions = null; + } + + public function testEncode() + { + $cookie = new RememberMeCookie($this->container); + $this->assertEquals('a|b', $cookie->encode('a', 'b')); + } + + public function testDecode() + { + $cookie = new RememberMeCookie($this->container); + $this->assertEquals(array('token' => 'a', 'sequence' => 'b'), $cookie->decode('a|b')); + } + + public function testHasCookie() + { + $this->container['request'] = new Request($this->container, array(), array(), array(), array(), array()); + + $cookie = new RememberMeCookie($this->container); + $this->assertFalse($cookie->hasCookie()); + + $this->container['request'] = new Request($this->container, array(), array(), array(), array(), array(RememberMeCookie::COOKIE_NAME => 'miam')); + $this->assertTrue($cookie->hasCookie()); + } + + public function testWrite() + { + self::$functions + ->expects($this->once()) + ->method('setcookie') + ->with( + RememberMeCookie::COOKIE_NAME, + 'myToken|mySequence', + 1234, + '', + '', + false, + true + ) + ->will($this->returnValue(true)); + + $cookie = new RememberMeCookie($this->container); + $this->assertTrue($cookie->write('myToken', 'mySequence', 1234)); + } + + public function testRead() + { + $this->container['request'] = new Request($this->container, array(), array(), array(), array(), array()); + + $cookie = new RememberMeCookie($this->container); + $this->assertFalse($cookie->read()); + + $this->container['request'] = new Request($this->container, array(), array(), array(), array(), array(RememberMeCookie::COOKIE_NAME => 'T|S')); + + $this->assertEquals(array('token' => 'T', 'sequence' => 'S'), $cookie->read()); + } + + public function testRemove() + { + self::$functions + ->expects($this->once()) + ->method('setcookie') + ->with( + RememberMeCookie::COOKIE_NAME, + '', + time() - 3600, + '', + '', + false, + true + ) + ->will($this->returnValue(true)); + + $cookie = new RememberMeCookie($this->container); + $this->assertTrue($cookie->remove()); + } +} diff --git a/tests/units/Core/Http/RequestTest.php b/tests/units/Core/Http/RequestTest.php new file mode 100644 index 00000000..217698f9 --- /dev/null +++ b/tests/units/Core/Http/RequestTest.php @@ -0,0 +1,175 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Http\Request; + +class RequestTest extends Base +{ + public function testGetStringParam() + { + $request = new Request($this->container, array(), array(), array(), array(), array()); + $this->assertEquals('', $request->getStringParam('myvar')); + + $request = new Request($this->container, array(), array(), array(), array(), array()); + $this->assertEquals('default', $request->getStringParam('myvar', 'default')); + + $request = new Request($this->container, array(), array('myvar' => 'myvalue'), array(), array(), array()); + $this->assertEquals('myvalue', $request->getStringParam('myvar')); + } + + public function testGetIntegerParam() + { + $request = new Request($this->container, array(), array(), array(), array(), array()); + $this->assertEquals(0, $request->getIntegerParam('myvar')); + + $request = new Request($this->container, array(), array(), array(), array(), array()); + $this->assertEquals(5, $request->getIntegerParam('myvar', 5)); + + $request = new Request($this->container, array(), array('myvar' => 'myvalue'), array(), array(), array()); + $this->assertEquals(0, $request->getIntegerParam('myvar')); + + $request = new Request($this->container, array(), array('myvar' => '123'), array(), array(), array()); + $this->assertEquals(123, $request->getIntegerParam('myvar')); + } + + public function testGetValues() + { + $request = new Request($this->container, array(), array(), array('myvar' => 'myvalue'), array(), array()); + $this->assertEmpty($request->getValue('myvar')); + + $request = new Request($this->container, array(), array(), array('myvar' => 'myvalue', 'csrf_token' => $this->container['token']->getCSRFToken()), array(), array()); + $this->assertEquals('myvalue', $request->getValue('myvar')); + + $request = new Request($this->container, array(), array(), array('myvar' => 'myvalue', 'csrf_token' => $this->container['token']->getCSRFToken()), array(), array()); + $this->assertEquals(array('myvar' => 'myvalue'), $request->getValues()); + } + + public function testGetFileContent() + { + $request = new Request($this->container, array(), array(), array(), array(), array()); + $this->assertEmpty($request->getFileContent('myfile')); + + $filename = tempnam(sys_get_temp_dir(), 'UnitTest'); + file_put_contents($filename, 'something'); + + $request = new Request($this->container, array(), array(), array(), array('myfile' => array('tmp_name' => $filename)), array()); + $this->assertEquals('something', $request->getFileContent('myfile')); + + unlink($filename); + } + + public function testGetFilePath() + { + $request = new Request($this->container, array(), array(), array(), array(), array()); + $this->assertEmpty($request->getFilePath('myfile')); + + $request = new Request($this->container, array(), array(), array(), array('myfile' => array('tmp_name' => 'somewhere')), array()); + $this->assertEquals('somewhere', $request->getFilePath('myfile')); + } + + public function testIsPost() + { + $request = new Request($this->container, array(), array(), array(), array(), array()); + $this->assertFalse($request->isPost()); + + $request = new Request($this->container, array('REQUEST_METHOD' => 'POST'), array(), array(), array(), array()); + $this->assertTrue($request->isPost()); + } + + public function testIsAjax() + { + $request = new Request($this->container, array(), array(), array(), array(), array()); + $this->assertFalse($request->isAjax()); + + $request = new Request($this->container, array('HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest'), array(), array(), array(), array()); + $this->assertTrue($request->isAjax()); + } + + public function testIsHTTPS() + { + $request = new Request($this->container, array(), array(), array(), array()); + $this->assertFalse($request->isHTTPS()); + + $request = new Request($this->container, array('HTTPS' => ''), array(), array(), array(), array()); + $this->assertFalse($request->isHTTPS()); + + $request = new Request($this->container, array('HTTPS' => 'off'), array(), array(), array(), array()); + $this->assertFalse($request->isHTTPS()); + + $request = new Request($this->container, array('HTTPS' => 'on'), array(), array(), array(), array()); + $this->assertTrue($request->isHTTPS()); + + $request = new Request($this->container, array('HTTPS' => '1'), array(), array(), array(), array()); + $this->assertTrue($request->isHTTPS()); + } + + public function testGetCookie() + { + $request = new Request($this->container, array(), array(), array(), array(), array()); + $this->assertEmpty($request->getCookie('mycookie')); + + $request = new Request($this->container, array(), array(), array(), array(), array('mycookie' => 'miam')); + $this->assertEquals('miam', $request->getCookie('mycookie')); + } + + public function testGetHeader() + { + $request = new Request($this->container, array(), array(), array(), array(), array()); + $this->assertEmpty($request->getHeader('X-Forwarded-For')); + + $request = new Request($this->container, array('HTTP_X_FORWARDED_FOR' => 'test'), array(), array(), array(), array()); + $this->assertEquals('test', $request->getHeader('X-Forwarded-For')); + } + + public function testGetRemoteUser() + { + $request = new Request($this->container, array(), array(), array(), array(), array()); + $this->assertEmpty($request->getRemoteUser()); + + $request = new Request($this->container, array(REVERSE_PROXY_USER_HEADER => 'test'), array(), array(), array(), array()); + $this->assertEquals('test', $request->getRemoteUser()); + } + + public function testGetQueryString() + { + $request = new Request($this->container, array(), array(), array(), array(), array()); + $this->assertEmpty($request->getQueryString()); + + $request = new Request($this->container, array('QUERY_STRING' => 'k=v'), array(), array(), array(), array()); + $this->assertEquals('k=v', $request->getQueryString()); + } + + public function testGetUri() + { + $request = new Request($this->container, array(), array(), array(), array(), array()); + $this->assertEmpty($request->getUri()); + + $request = new Request($this->container, array('REQUEST_URI' => '/blah'), array(), array(), array(), array()); + $this->assertEquals('/blah', $request->getUri()); + } + + public function testGetUserAgent() + { + $request = new Request($this->container, array(), array(), array(), array(), array()); + $this->assertEquals('Unknown', $request->getUserAgent()); + + $request = new Request($this->container, array('HTTP_USER_AGENT' => 'My browser'), array(), array(), array(), array()); + $this->assertEquals('My browser', $request->getUserAgent()); + } + + public function testGetIpAddress() + { + $request = new Request($this->container, array(), array(), array(), array(), array()); + $this->assertEquals('Unknown', $request->getIpAddress()); + + $request = new Request($this->container, array('HTTP_X_FORWARDED_FOR' => '192.168.0.1,127.0.0.1'), array(), array(), array(), array()); + $this->assertEquals('192.168.0.1', $request->getIpAddress()); + + $request = new Request($this->container, array('REMOTE_ADDR' => '192.168.0.1'), array(), array(), array(), array()); + $this->assertEquals('192.168.0.1', $request->getIpAddress()); + + $request = new Request($this->container, array('REMOTE_ADDR' => ''), array(), array(), array(), array()); + $this->assertEquals('Unknown', $request->getIpAddress()); + } +} diff --git a/tests/units/Core/Http/RouteTest.php b/tests/units/Core/Http/RouteTest.php new file mode 100644 index 00000000..5e44ad00 --- /dev/null +++ b/tests/units/Core/Http/RouteTest.php @@ -0,0 +1,79 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Http\Route; + +class RouteTest extends Base +{ + public function testFindParams() + { + $route = new Route($this->container); + $route->enable(); + + $this->assertEquals(array('p1' => true, 'p2' => true), $route->findParams(array('something', ':p1', ':p2'))); + $this->assertEquals(array('p1' => true), $route->findParams(array('something', ':p1', ''))); + $this->assertEquals(array('p1' => true), $route->findParams(array('something', ':p1', 'something else'))); + } + + public function testFindRoute() + { + $route = new Route($this->container); + $route->enable(); + + $route->addRoute('/mycontroller/myaction', 'mycontroller', 'myaction'); + $this->assertEquals( + array('controller' => 'mycontroller', 'action' => 'myaction', 'plugin' => ''), + $route->findRoute('/mycontroller/myaction') + ); + + $route->addRoute('/a/b/c', 'mycontroller', 'myaction', 'myplugin'); + $this->assertEquals( + array('controller' => 'mycontroller', 'action' => 'myaction', 'plugin' => 'myplugin'), + $route->findRoute('/a/b/c') + ); + + $this->assertEquals( + array('controller' => 'app', 'action' => 'index', 'plugin' => ''), + $route->findRoute('/notfound') + ); + + $route->addRoute('/a/b/:c', 'mycontroller', 'myaction', 'myplugin'); + $this->assertEquals( + array('controller' => 'mycontroller', 'action' => 'myaction', 'plugin' => 'myplugin'), + $route->findRoute('/a/b/myvalue') + ); + + $this->assertEquals('myvalue', $this->container['request']->getStringParam('c')); + + $route->addRoute('/a/:p1/b/:p2', 'mycontroller', 'myaction'); + $this->assertEquals( + array('controller' => 'mycontroller', 'action' => 'myaction', 'plugin' => ''), + $route->findRoute('/a/v1/b/v2') + ); + + $this->assertEquals('v1', $this->container['request']->getStringParam('p1')); + $this->assertEquals('v2', $this->container['request']->getStringParam('p2')); + } + + public function testFindUrl() + { + $route = new Route($this->container); + $route->enable(); + $route->addRoute('a/b', 'controller1', 'action1'); + $route->addRoute('a/:myvar1/b/:myvar2', 'controller2', 'action2'); + $route->addRoute('/something', 'controller1', 'action1', 'myplugin'); + $route->addRoute('/myplugin/myroute', 'controller1', 'action2', 'myplugin'); + $route->addRoute('/foo/:myvar', 'controller1', 'action3', 'myplugin'); + + $this->assertEquals('a/1/b/2', $route->findUrl('controller2', 'action2', array('myvar1' => 1, 'myvar2' => 2))); + $this->assertEquals('', $route->findUrl('controller2', 'action2', array('myvar1' => 1))); + $this->assertEquals('a/b', $route->findUrl('controller1', 'action1')); + $this->assertEquals('', $route->findUrl('controller1', 'action2')); + + $this->assertEquals('myplugin/myroute', $route->findUrl('controller1', 'action2', array(), 'myplugin')); + $this->assertEquals('something', $route->findUrl('controller1', 'action1', array(), 'myplugin')); + $this->assertEquals('foo/123', $route->findUrl('controller1', 'action3', array('myvar' => 123), 'myplugin')); + $this->assertEquals('foo/123', $route->findUrl('controller1', 'action3', array('myvar' => 123, 'plugin' => 'myplugin'))); + } +} diff --git a/tests/units/Core/Http/RouterTest.php b/tests/units/Core/Http/RouterTest.php new file mode 100644 index 00000000..0b200ab5 --- /dev/null +++ b/tests/units/Core/Http/RouterTest.php @@ -0,0 +1,203 @@ +<?php + +namespace Kanboard\Controller { + + class FakeController { + public function beforeAction() {} + public function myAction() {} + } +} + +namespace Kanboard\Plugin\Myplugin\Controller { + + class FakeController { + public function beforeAction() {} + public function myAction() {} + } +} + +namespace { + + require_once __DIR__.'/../../Base.php'; + + use Kanboard\Core\Helper; + use Kanboard\Core\Http\Route; + use Kanboard\Core\Http\Router; + use Kanboard\Core\Http\Request; + + class RouterTest extends Base + { + public function testSanitize() + { + $dispatcher = new Router($this->container); + + $this->assertEquals('PloP', $dispatcher->sanitize('PloP', 'default')); + $this->assertEquals('default', $dispatcher->sanitize('', 'default')); + $this->assertEquals('default', $dispatcher->sanitize('123-AB', 'default')); + $this->assertEquals('default', $dispatcher->sanitize('R&D', 'default')); + $this->assertEquals('Test123', $dispatcher->sanitize('Test123', 'default')); + $this->assertEquals('Test_123', $dispatcher->sanitize('Test_123', 'default')); + $this->assertEquals('userImport', $dispatcher->sanitize('userImport', 'default')); + } + + public function testGetPath() + { + $dispatcher = new Router($this->container); + + $this->container['helper'] = new Helper($this->container); + $this->container['request'] = new Request($this->container, array('PHP_SELF' => '/index.php', 'REQUEST_URI' => '/a/b/c', 'REQUEST_METHOD' => 'GET')); + $this->assertEquals('a/b/c', $dispatcher->getPath()); + + $this->container['helper'] = new Helper($this->container); + $this->container['request'] = new Request($this->container, array('PHP_SELF' => '/index.php', 'REQUEST_URI' => '/a/b/something?test=a', 'QUERY_STRING' => 'test=a', 'REQUEST_METHOD' => 'GET')); + $this->assertEquals('a/b/something', $dispatcher->getPath()); + + $this->container['helper'] = new Helper($this->container); + $this->container['request'] = new Request($this->container, array('PHP_SELF' => '/a/index.php', 'REQUEST_URI' => '/a/b/something?test=a', 'QUERY_STRING' => 'test=a', 'REQUEST_METHOD' => 'GET')); + $this->assertEquals('b/something', $dispatcher->getPath()); + } + + public function testDispatcherWithControllerNotFound() + { + $this->container['request'] = new Request($this->container, array( + 'PHP_SELF' => '/kanboard/index.php', + 'REQUEST_URI' => '/kanboard/?controller=FakeControllerNotFound&action=myAction&myvar=value1', + 'QUERY_STRING' => 'controller=FakeControllerNotFound&action=myAction&myvar=value1', + 'REQUEST_METHOD' => 'GET' + ), + array( + 'controller' => 'FakeControllerNotFound', + 'action' => 'myAction', + 'myvar' => 'value1', + ) + ); + + $this->setExpectedException('RuntimeException', 'Controller not found'); + + $dispatcher = new Router($this->container); + $dispatcher->dispatch(); + } + + public function testDispatcherWithActionNotFound() + { + $this->container['request'] = new Request($this->container, array( + 'PHP_SELF' => '/kanboard/index.php', + 'REQUEST_URI' => '/kanboard/?controller=FakeController&action=myActionNotFound&myvar=value1', + 'QUERY_STRING' => 'controller=FakeController&action=myActionNotFound&myvar=value1', + 'REQUEST_METHOD' => 'GET' + ), + array( + 'controller' => 'FakeController', + 'action' => 'myActionNotFound', + 'myvar' => 'value1', + ) + ); + + $this->setExpectedException('RuntimeException', 'Action not implemented'); + + $dispatcher = new Router($this->container); + $dispatcher->dispatch(); + } + + public function testDispatcherWithNoUrlRewrite() + { + $this->container['request'] = new Request($this->container, array( + 'PHP_SELF' => '/kanboard/index.php', + 'REQUEST_URI' => '/kanboard/?controller=FakeController&action=myAction&myvar=value1', + 'QUERY_STRING' => 'controller=FakeController&action=myAction&myvar=value1', + 'REQUEST_METHOD' => 'GET' + ), + array( + 'controller' => 'FakeController', + 'action' => 'myAction', + 'myvar' => 'value1', + ) + ); + + $dispatcher = new Router($this->container); + $this->assertInstanceOf('\Kanboard\Controller\FakeController', $dispatcher->dispatch()); + $this->assertEquals('FakeController', $dispatcher->getController()); + $this->assertEquals('myAction', $dispatcher->getAction()); + $this->assertEquals('', $dispatcher->getPlugin()); + $this->assertEquals('value1', $this->container['request']->getStringParam('myvar')); + } + + public function testDispatcherWithNoUrlRewriteAndPlugin() + { + $this->container['request'] = new Request($this->container, array( + 'PHP_SELF' => '/kanboard/index.php', + 'REQUEST_URI' => '/kanboard/?controller=FakeController&action=myAction&myvar=value1&plugin=myplugin', + 'QUERY_STRING' => 'controller=FakeController&action=myAction&myvar=value1&plugin=myplugin', + 'REQUEST_METHOD' => 'GET' + ), + array( + 'controller' => 'FakeController', + 'action' => 'myAction', + 'myvar' => 'value1', + 'plugin' => 'myplugin', + ) + ); + + $dispatcher = new Router($this->container); + $this->assertInstanceOf('\Kanboard\Plugin\Myplugin\Controller\FakeController', $dispatcher->dispatch()); + $this->assertEquals('FakeController', $dispatcher->getController()); + $this->assertEquals('myAction', $dispatcher->getAction()); + $this->assertEquals('Myplugin', $dispatcher->getPlugin()); + $this->assertEquals('value1', $this->container['request']->getStringParam('myvar')); + } + + public function testDispatcherWithUrlRewrite() + { + $this->container['request'] = new Request($this->container, array( + 'PHP_SELF' => '/kanboard/index.php', + 'REQUEST_URI' => '/kanboard/my/route/123?myvar=value1', + 'QUERY_STRING' => 'myvar=value1', + 'REQUEST_METHOD' => 'GET' + ), + array( + 'myvar' => 'value1', + ) + ); + + $this->container['route'] = new Route($this->container); + $this->container['route']->enable(); + $dispatcher = new Router($this->container); + + $this->container['route']->addRoute('/my/route/:param', 'FakeController', 'myAction'); + + $this->assertInstanceOf('\Kanboard\Controller\FakeController', $dispatcher->dispatch()); + $this->assertEquals('FakeController', $dispatcher->getController()); + $this->assertEquals('myAction', $dispatcher->getAction()); + $this->assertEquals('', $dispatcher->getPlugin()); + $this->assertEquals('value1', $this->container['request']->getStringParam('myvar')); + $this->assertEquals('123', $this->container['request']->getStringParam('param')); + } + + public function testDispatcherWithUrlRewriteWithPlugin() + { + $this->container['request'] = new Request($this->container, array( + 'PHP_SELF' => '/kanboard/index.php', + 'REQUEST_URI' => '/kanboard/my/plugin/route/123?myvar=value1', + 'QUERY_STRING' => 'myvar=value1', + 'REQUEST_METHOD' => 'GET' + ), + array( + 'myvar' => 'value1', + ) + ); + + $this->container['route'] = new Route($this->container); + $this->container['route']->enable(); + $dispatcher = new Router($this->container); + + $this->container['route']->addRoute('/my/plugin/route/:param', 'fakeController', 'myAction', 'Myplugin'); + + $this->assertInstanceOf('\Kanboard\Plugin\Myplugin\Controller\FakeController', $dispatcher->dispatch()); + $this->assertEquals('FakeController', $dispatcher->getController()); + $this->assertEquals('myAction', $dispatcher->getAction()); + $this->assertEquals('Myplugin', $dispatcher->getPlugin()); + $this->assertEquals('value1', $this->container['request']->getStringParam('myvar')); + $this->assertEquals('123', $this->container['request']->getStringParam('param')); + } + } +} diff --git a/tests/units/Core/Ldap/ClientTest.php b/tests/units/Core/Ldap/ClientTest.php new file mode 100644 index 00000000..d149500e --- /dev/null +++ b/tests/units/Core/Ldap/ClientTest.php @@ -0,0 +1,220 @@ +<?php + +namespace Kanboard\Core\Ldap; + +require_once __DIR__.'/../../Base.php'; + +function ldap_connect($hostname, $port) +{ + return ClientTest::$functions->ldap_connect($hostname, $port); +} + +function ldap_set_option() +{ +} + +function ldap_bind($link_identifier, $bind_rdn = null, $bind_password = null) +{ + return ClientTest::$functions->ldap_bind($link_identifier, $bind_rdn, $bind_password); +} + +function ldap_start_tls($link_identifier) +{ + return ClientTest::$functions->ldap_start_tls($link_identifier); +} + +class ClientTest extends \Base +{ + public static $functions; + private $ldap; + + public function setUp() + { + parent::setup(); + + self::$functions = $this + ->getMockBuilder('stdClass') + ->setMethods(array( + 'ldap_connect', + 'ldap_set_option', + 'ldap_bind', + 'ldap_start_tls', + )) + ->getMock(); + } + + public function tearDown() + { + parent::tearDown(); + self::$functions = null; + } + + public function testGetLdapServerNotConfigured() + { + $this->setExpectedException('\LogicException'); + $ldap = new Client; + $ldap->getLdapServer(); + } + + public function testConnectSuccess() + { + self::$functions + ->expects($this->once()) + ->method('ldap_connect') + ->with( + $this->equalTo('my_ldap_server'), + $this->equalTo(389) + ) + ->will($this->returnValue('my_ldap_resource')); + + $ldap = new Client; + $ldap->open('my_ldap_server'); + $this->assertEquals('my_ldap_resource', $ldap->getConnection()); + } + + public function testConnectFailure() + { + self::$functions + ->expects($this->once()) + ->method('ldap_connect') + ->with( + $this->equalTo('my_ldap_server'), + $this->equalTo(389) + ) + ->will($this->returnValue(false)); + + $this->setExpectedException('\Kanboard\Core\Ldap\ClientException'); + + $ldap = new Client; + $ldap->open('my_ldap_server'); + $this->assertNotEquals('my_ldap_resource', $ldap->getConnection()); + } + + public function testConnectSuccessWithTLS() + { + self::$functions + ->expects($this->once()) + ->method('ldap_connect') + ->with( + $this->equalTo('my_ldap_server'), + $this->equalTo(389) + ) + ->will($this->returnValue('my_ldap_resource')); + + self::$functions + ->expects($this->once()) + ->method('ldap_start_tls') + ->with( + $this->equalTo('my_ldap_resource') + ) + ->will($this->returnValue(true)); + + $ldap = new Client; + $ldap->open('my_ldap_server', 389, true); + $this->assertEquals('my_ldap_resource', $ldap->getConnection()); + } + + public function testConnectFailureWithTLS() + { + self::$functions + ->expects($this->once()) + ->method('ldap_connect') + ->with( + $this->equalTo('my_ldap_server'), + $this->equalTo(389) + ) + ->will($this->returnValue('my_ldap_resource')); + + self::$functions + ->expects($this->once()) + ->method('ldap_start_tls') + ->with( + $this->equalTo('my_ldap_resource') + ) + ->will($this->returnValue(false)); + + $this->setExpectedException('\Kanboard\Core\Ldap\ClientException'); + + $ldap = new Client; + $ldap->open('my_ldap_server', 389, true); + $this->assertNotEquals('my_ldap_resource', $ldap->getConnection()); + } + + public function testAnonymousAuthenticationSuccess() + { + self::$functions + ->expects($this->once()) + ->method('ldap_bind') + ->will($this->returnValue(true)); + + $ldap = new Client; + $this->assertTrue($ldap->useAnonymousAuthentication()); + } + + public function testAnonymousAuthenticationFailure() + { + self::$functions + ->expects($this->once()) + ->method('ldap_bind') + ->will($this->returnValue(false)); + + $this->setExpectedException('\Kanboard\Core\Ldap\ClientException'); + + $ldap = new Client; + $ldap->useAnonymousAuthentication(); + } + + public function testUserAuthenticationSuccess() + { + self::$functions + ->expects($this->once()) + ->method('ldap_connect') + ->with( + $this->equalTo('my_ldap_server'), + $this->equalTo(389) + ) + ->will($this->returnValue('my_ldap_resource')); + + self::$functions + ->expects($this->once()) + ->method('ldap_bind') + ->with( + $this->equalTo('my_ldap_resource'), + $this->equalTo('my_ldap_user'), + $this->equalTo('my_ldap_password') + ) + ->will($this->returnValue(true)); + + $ldap = new Client; + $ldap->open('my_ldap_server'); + $this->assertTrue($ldap->authenticate('my_ldap_user', 'my_ldap_password')); + } + + public function testUserAuthenticationFailure() + { + self::$functions + ->expects($this->once()) + ->method('ldap_connect') + ->with( + $this->equalTo('my_ldap_server'), + $this->equalTo(389) + ) + ->will($this->returnValue('my_ldap_resource')); + + self::$functions + ->expects($this->once()) + ->method('ldap_bind') + ->with( + $this->equalTo('my_ldap_resource'), + $this->equalTo('my_ldap_user'), + $this->equalTo('my_ldap_password') + ) + ->will($this->returnValue(false)); + + $this->setExpectedException('\Kanboard\Core\Ldap\ClientException'); + + $ldap = new Client; + $ldap->open('my_ldap_server'); + $ldap->authenticate('my_ldap_user', 'my_ldap_password'); + } +} diff --git a/tests/units/Core/Ldap/EntriesTest.php b/tests/units/Core/Ldap/EntriesTest.php new file mode 100644 index 00000000..65025b6e --- /dev/null +++ b/tests/units/Core/Ldap/EntriesTest.php @@ -0,0 +1,55 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Ldap\Entries; + +class EntriesTest extends Base +{ + private $entries = array( + 'count' => 2, + 0 => array( + 'cn' => array( + 'count' => 1, + 0 => 'Kanboard Other Group', + ), + 0 => 'cn', + 'count' => 1, + 'dn' => 'CN=Kanboard Other Group,CN=Users,DC=kanboard,DC=local', + ), + 1 => array( + 'cn' => array( + 'count' => 1, + 0 => 'Kanboard Users', + ), + 0 => 'cn', + 'count' => 1, + 'dn' => 'CN=Kanboard Users,CN=Users,DC=kanboard,DC=local', + ), + ); + + public function testGetAll() + { + $entries = new Entries(array()); + $this->assertEmpty($entries->getAll()); + + $entries = new Entries($this->entries); + $result = $entries->getAll(); + $this->assertCount(2, $result); + $this->assertInstanceOf('Kanboard\Core\Ldap\Entry', $result[0]); + $this->assertEquals('CN=Kanboard Users,CN=Users,DC=kanboard,DC=local', $result[1]->getDn()); + $this->assertEquals('Kanboard Users', $result[1]->getFirstValue('cn')); + } + + public function testGetFirst() + { + $entries = new Entries(array()); + $this->assertEquals('', $entries->getFirstEntry()->getDn()); + + $entries = new Entries($this->entries); + $result = $entries->getFirstEntry(); + $this->assertInstanceOf('Kanboard\Core\Ldap\Entry', $result); + $this->assertEquals('CN=Kanboard Other Group,CN=Users,DC=kanboard,DC=local', $result->getDn()); + $this->assertEquals('Kanboard Other Group', $result->getFirstValue('cn')); + } +} diff --git a/tests/units/Core/Ldap/EntryTest.php b/tests/units/Core/Ldap/EntryTest.php new file mode 100644 index 00000000..45585e77 --- /dev/null +++ b/tests/units/Core/Ldap/EntryTest.php @@ -0,0 +1,71 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Ldap\Entry; + +class EntryTest extends Base +{ + private $entry = array( + 'count' => 2, + 'dn' => 'uid=my_user,ou=People,dc=kanboard,dc=local', + 'displayname' => array( + 'count' => 1, + 0 => 'My LDAP user', + ), + 'broken' => array( + ), + 'mail' => array( + 'count' => 2, + 0 => 'user1@localhost', + 1 => 'user2@localhost', + ), + 'samaccountname' => array( + 'count' => 1, + 0 => 'my_ldap_user', + ), + 0 => 'displayname', + 1 => 'mail', + 2 => 'samaccountname', + ); + + public function testGetAll() + { + $expected = array( + 'user1@localhost', + 'user2@localhost', + ); + + $entry = new Entry($this->entry); + $this->assertEquals($expected, $entry->getAll('mail')); + $this->assertEmpty($entry->getAll('not found')); + $this->assertEmpty($entry->getAll('broken')); + } + + public function testGetFirst() + { + $entry = new Entry($this->entry); + $this->assertEquals('user1@localhost', $entry->getFirstValue('mail')); + $this->assertEquals('', $entry->getFirstValue('not found')); + $this->assertEquals('default', $entry->getFirstValue('not found', 'default')); + $this->assertEquals('default', $entry->getFirstValue('broken', 'default')); + } + + public function testGetDn() + { + $entry = new Entry($this->entry); + $this->assertEquals('uid=my_user,ou=People,dc=kanboard,dc=local', $entry->getDn()); + + $entry = new Entry(array()); + $this->assertEquals('', $entry->getDn()); + } + + public function testHasValue() + { + $entry = new Entry($this->entry); + $this->assertTrue($entry->hasValue('mail', 'user2@localhost')); + $this->assertFalse($entry->hasValue('mail', 'user3@localhost')); + $this->assertTrue($entry->hasValue('displayname', 'My LDAP user')); + $this->assertFalse($entry->hasValue('displayname', 'Something else')); + } +} diff --git a/tests/units/Core/Ldap/LdapGroupTest.php b/tests/units/Core/Ldap/LdapGroupTest.php new file mode 100644 index 00000000..3f538249 --- /dev/null +++ b/tests/units/Core/Ldap/LdapGroupTest.php @@ -0,0 +1,160 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Ldap\Group; +use Kanboard\Core\Ldap\Entries; +use Kanboard\Core\Security\Role; + +class LdapGroupTest extends Base +{ + private $query; + private $client; + private $group; + + public function setUp() + { + parent::setUp(); + + $this->client = $this + ->getMockBuilder('\Kanboard\Core\Ldap\Client') + ->setMethods(array( + 'getConnection', + )) + ->getMock(); + + $this->query = $this + ->getMockBuilder('\Kanboard\Core\Ldap\Query') + ->setConstructorArgs(array($this->client)) + ->setMethods(array( + 'execute', + 'hasResult', + 'getEntries', + )) + ->getMock(); + + $this->group = $this + ->getMockBuilder('\Kanboard\Core\Ldap\Group') + ->setConstructorArgs(array($this->query)) + ->setMethods(array( + 'getAttributeName', + 'getBasDn', + )) + ->getMock(); + } + + public function testGetGroups() + { + $entries = new Entries(array( + 'count' => 2, + 0 => array( + 'cn' => array( + 'count' => 1, + 0 => 'Kanboard Other Group', + ), + 0 => 'cn', + 'count' => 1, + 'dn' => 'CN=Kanboard Other Group,CN=Users,DC=kanboard,DC=local', + ), + 1 => array( + 'cn' => array( + 'count' => 1, + 0 => 'Kanboard Users', + ), + 0 => 'cn', + 'count' => 1, + 'dn' => 'CN=Kanboard Users,CN=Users,DC=kanboard,DC=local', + ), + )); + + $this->client + ->expects($this->any()) + ->method('getConnection') + ->will($this->returnValue('my_ldap_resource')); + + $this->query + ->expects($this->once()) + ->method('execute') + ->with( + $this->equalTo('CN=Users,DC=kanboard,DC=local'), + $this->equalTo('(&(objectClass=group)(sAMAccountName=Kanboard*))') + ); + + $this->query + ->expects($this->once()) + ->method('hasResult') + ->will($this->returnValue(true)); + + $this->query + ->expects($this->once()) + ->method('getEntries') + ->will($this->returnValue($entries)); + + $this->group + ->expects($this->any()) + ->method('getAttributeName') + ->will($this->returnValue('cn')); + + $this->group + ->expects($this->any()) + ->method('getBasDn') + ->will($this->returnValue('CN=Users,DC=kanboard,DC=local')); + + $groups = $this->group->find('(&(objectClass=group)(sAMAccountName=Kanboard*))'); + $this->assertCount(2, $groups); + $this->assertInstanceOf('Kanboard\Group\LdapGroupProvider', $groups[0]); + $this->assertInstanceOf('Kanboard\Group\LdapGroupProvider', $groups[1]); + $this->assertEquals('Kanboard Other Group', $groups[0]->getName()); + $this->assertEquals('Kanboard Users', $groups[1]->getName()); + $this->assertEquals('CN=Kanboard Other Group,CN=Users,DC=kanboard,DC=local', $groups[0]->getExternalId()); + $this->assertEquals('CN=Kanboard Users,CN=Users,DC=kanboard,DC=local', $groups[1]->getExternalId()); + } + + public function testGetGroupsWithNoResult() + { + $entries = new Entries(array()); + + $this->client + ->expects($this->any()) + ->method('getConnection') + ->will($this->returnValue('my_ldap_resource')); + + $this->query + ->expects($this->once()) + ->method('execute') + ->with( + $this->equalTo('CN=Users,DC=kanboard,DC=local'), + $this->equalTo('(&(objectClass=group)(sAMAccountName=Kanboard*))') + ); + + $this->query + ->expects($this->once()) + ->method('hasResult') + ->will($this->returnValue(false)); + + $this->query + ->expects($this->never()) + ->method('getEntries'); + + $this->group + ->expects($this->any()) + ->method('getAttributeName') + ->will($this->returnValue('cn')); + + $this->group + ->expects($this->any()) + ->method('getBasDn') + ->will($this->returnValue('CN=Users,DC=kanboard,DC=local')); + + $groups = $this->group->find('(&(objectClass=group)(sAMAccountName=Kanboard*))'); + $this->assertCount(0, $groups); + } + + public function testGetBaseDnNotConfigured() + { + $this->setExpectedException('\LogicException'); + + $group = new Group($this->query); + $group->getBasDn(); + } +} diff --git a/tests/units/Core/Ldap/LdapUserTest.php b/tests/units/Core/Ldap/LdapUserTest.php new file mode 100644 index 00000000..2b3db1e5 --- /dev/null +++ b/tests/units/Core/Ldap/LdapUserTest.php @@ -0,0 +1,379 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Ldap\User; +use Kanboard\Core\Ldap\Entries; +use Kanboard\Core\Security\Role; + +class LdapUserTest extends Base +{ + private $query; + private $client; + private $user; + + public function setUp() + { + parent::setUp(); + + $this->client = $this + ->getMockBuilder('\Kanboard\Core\Ldap\Client') + ->setMethods(array( + 'getConnection', + )) + ->getMock(); + + $this->query = $this + ->getMockBuilder('\Kanboard\Core\Ldap\Query') + ->setConstructorArgs(array($this->client)) + ->setMethods(array( + 'execute', + 'hasResult', + 'getEntries', + )) + ->getMock(); + + $this->user = $this + ->getMockBuilder('\Kanboard\Core\Ldap\User') + ->setConstructorArgs(array($this->query)) + ->setMethods(array( + 'getAttributeUsername', + 'getAttributeEmail', + 'getAttributeName', + 'getAttributeGroup', + 'getGroupAdminDn', + 'getGroupManagerDn', + 'getBasDn', + )) + ->getMock(); + } + + public function testGetUser() + { + $entries = new Entries(array( + 'count' => 1, + 0 => array( + 'count' => 2, + 'dn' => 'uid=my_ldap_user,ou=People,dc=kanboard,dc=local', + 'displayname' => array( + 'count' => 1, + 0 => 'My LDAP user', + ), + 'mail' => array( + 'count' => 2, + 0 => 'user1@localhost', + 1 => 'user2@localhost', + ), + 'samaccountname' => array( + 'count' => 1, + 0 => 'my_ldap_user', + ), + 0 => 'displayname', + 1 => 'mail', + 2 => 'samaccountname', + ) + )); + + $this->client + ->expects($this->any()) + ->method('getConnection') + ->will($this->returnValue('my_ldap_resource')); + + $this->query + ->expects($this->once()) + ->method('execute') + ->with( + $this->equalTo('ou=People,dc=kanboard,dc=local'), + $this->equalTo('(uid=my_ldap_user)') + ); + + $this->query + ->expects($this->once()) + ->method('hasResult') + ->will($this->returnValue(true)); + + $this->query + ->expects($this->once()) + ->method('getEntries') + ->will($this->returnValue($entries)); + + $this->user + ->expects($this->any()) + ->method('getAttributeUsername') + ->will($this->returnValue('samaccountname')); + + $this->user + ->expects($this->any()) + ->method('getAttributeName') + ->will($this->returnValue('displayname')); + + $this->user + ->expects($this->any()) + ->method('getAttributeEmail') + ->will($this->returnValue('mail')); + + $this->user + ->expects($this->any()) + ->method('getBasDn') + ->will($this->returnValue('ou=People,dc=kanboard,dc=local')); + + $user = $this->user->find('(uid=my_ldap_user)'); + $this->assertInstanceOf('Kanboard\User\LdapUserProvider', $user); + $this->assertEquals('uid=my_ldap_user,ou=People,dc=kanboard,dc=local', $user->getDn()); + $this->assertEquals('my_ldap_user', $user->getUsername()); + $this->assertEquals('My LDAP user', $user->getName()); + $this->assertEquals('user1@localhost', $user->getEmail()); + $this->assertEquals(Role::APP_USER, $user->getRole()); + $this->assertEquals(array(), $user->getExternalGroupIds()); + $this->assertEquals(array('is_ldap_user' => 1), $user->getExtraAttributes()); + } + + public function testGetUserWithAdminRole() + { + $entries = new Entries(array( + 'count' => 1, + 0 => array( + 'count' => 2, + 'dn' => 'uid=my_ldap_user,ou=People,dc=kanboard,dc=local', + 'displayname' => array( + 'count' => 1, + 0 => 'My LDAP user', + ), + 'mail' => array( + 'count' => 2, + 0 => 'user1@localhost', + 1 => 'user2@localhost', + ), + 'samaccountname' => array( + 'count' => 1, + 0 => 'my_ldap_user', + ), + 'memberof' => array( + 'count' => 1, + 0 => 'CN=Kanboard-Admins,CN=Users,DC=kanboard,DC=local', + ), + 0 => 'displayname', + 1 => 'mail', + 2 => 'samaccountname', + 3 => 'memberof', + ) + )); + + $this->client + ->expects($this->any()) + ->method('getConnection') + ->will($this->returnValue('my_ldap_resource')); + + $this->query + ->expects($this->once()) + ->method('execute') + ->with( + $this->equalTo('ou=People,dc=kanboard,dc=local'), + $this->equalTo('(uid=my_ldap_user)') + ); + + $this->query + ->expects($this->once()) + ->method('hasResult') + ->will($this->returnValue(true)); + + $this->query + ->expects($this->once()) + ->method('getEntries') + ->will($this->returnValue($entries)); + + $this->user + ->expects($this->any()) + ->method('getAttributeUsername') + ->will($this->returnValue('samaccountname')); + + $this->user + ->expects($this->any()) + ->method('getAttributeName') + ->will($this->returnValue('displayname')); + + $this->user + ->expects($this->any()) + ->method('getAttributeEmail') + ->will($this->returnValue('mail')); + + $this->user + ->expects($this->any()) + ->method('getAttributeGroup') + ->will($this->returnValue('memberof')); + + $this->user + ->expects($this->any()) + ->method('getGroupAdminDn') + ->will($this->returnValue('CN=Kanboard-Admins,CN=Users,DC=kanboard,DC=local')); + + $this->user + ->expects($this->any()) + ->method('getBasDn') + ->will($this->returnValue('ou=People,dc=kanboard,dc=local')); + + $user = $this->user->find('(uid=my_ldap_user)'); + $this->assertInstanceOf('Kanboard\User\LdapUserProvider', $user); + $this->assertEquals('uid=my_ldap_user,ou=People,dc=kanboard,dc=local', $user->getDn()); + $this->assertEquals('my_ldap_user', $user->getUsername()); + $this->assertEquals('My LDAP user', $user->getName()); + $this->assertEquals('user1@localhost', $user->getEmail()); + $this->assertEquals(Role::APP_ADMIN, $user->getRole()); + $this->assertEquals(array('CN=Kanboard-Admins,CN=Users,DC=kanboard,DC=local'), $user->getExternalGroupIds()); + $this->assertEquals(array('is_ldap_user' => 1), $user->getExtraAttributes()); + } + + public function testGetUserWithManagerRole() + { + $entries = new Entries(array( + 'count' => 1, + 0 => array( + 'count' => 2, + 'dn' => 'uid=my_ldap_user,ou=People,dc=kanboard,dc=local', + 'displayname' => array( + 'count' => 1, + 0 => 'My LDAP user', + ), + 'mail' => array( + 'count' => 2, + 0 => 'user1@localhost', + 1 => 'user2@localhost', + ), + 'samaccountname' => array( + 'count' => 1, + 0 => 'my_ldap_user', + ), + 'memberof' => array( + 'count' => 2, + 0 => 'CN=Kanboard-Users,CN=Users,DC=kanboard,DC=local', + 1 => 'CN=Kanboard-Managers,CN=Users,DC=kanboard,DC=local', + ), + 0 => 'displayname', + 1 => 'mail', + 2 => 'samaccountname', + 3 => 'memberof', + ) + )); + + $this->client + ->expects($this->any()) + ->method('getConnection') + ->will($this->returnValue('my_ldap_resource')); + + $this->query + ->expects($this->once()) + ->method('execute') + ->with( + $this->equalTo('ou=People,dc=kanboard,dc=local'), + $this->equalTo('(uid=my_ldap_user)') + ); + + $this->query + ->expects($this->once()) + ->method('hasResult') + ->will($this->returnValue(true)); + + $this->query + ->expects($this->once()) + ->method('getEntries') + ->will($this->returnValue($entries)); + + $this->user + ->expects($this->any()) + ->method('getAttributeUsername') + ->will($this->returnValue('samaccountname')); + + $this->user + ->expects($this->any()) + ->method('getAttributeName') + ->will($this->returnValue('displayname')); + + $this->user + ->expects($this->any()) + ->method('getAttributeEmail') + ->will($this->returnValue('mail')); + + $this->user + ->expects($this->any()) + ->method('getAttributeGroup') + ->will($this->returnValue('memberof')); + + $this->user + ->expects($this->any()) + ->method('getGroupManagerDn') + ->will($this->returnValue('CN=Kanboard-Managers,CN=Users,DC=kanboard,DC=local')); + + $this->user + ->expects($this->any()) + ->method('getBasDn') + ->will($this->returnValue('ou=People,dc=kanboard,dc=local')); + + $user = $this->user->find('(uid=my_ldap_user)'); + $this->assertInstanceOf('Kanboard\User\LdapUserProvider', $user); + $this->assertEquals('uid=my_ldap_user,ou=People,dc=kanboard,dc=local', $user->getDn()); + $this->assertEquals('my_ldap_user', $user->getUsername()); + $this->assertEquals('My LDAP user', $user->getName()); + $this->assertEquals('user1@localhost', $user->getEmail()); + $this->assertEquals(Role::APP_MANAGER, $user->getRole()); + $this->assertEquals(array('CN=Kanboard-Users,CN=Users,DC=kanboard,DC=local', 'CN=Kanboard-Managers,CN=Users,DC=kanboard,DC=local'), $user->getExternalGroupIds()); + $this->assertEquals(array('is_ldap_user' => 1), $user->getExtraAttributes()); + } + + public function testGetUserNotFound() + { + $entries = new Entries(array()); + + $this->client + ->expects($this->any()) + ->method('getConnection') + ->will($this->returnValue('my_ldap_resource')); + + $this->query + ->expects($this->once()) + ->method('execute') + ->with( + $this->equalTo('ou=People,dc=kanboard,dc=local'), + $this->equalTo('(uid=my_ldap_user)') + ); + + $this->query + ->expects($this->once()) + ->method('hasResult') + ->will($this->returnValue(false)); + + $this->query + ->expects($this->never()) + ->method('getEntries'); + + $this->user + ->expects($this->any()) + ->method('getAttributeUsername') + ->will($this->returnValue('samaccountname')); + + $this->user + ->expects($this->any()) + ->method('getAttributeName') + ->will($this->returnValue('displayname')); + + $this->user + ->expects($this->any()) + ->method('getAttributeEmail') + ->will($this->returnValue('mail')); + + $this->user + ->expects($this->any()) + ->method('getBasDn') + ->will($this->returnValue('ou=People,dc=kanboard,dc=local')); + + $user = $this->user->find('(uid=my_ldap_user)'); + $this->assertEquals(null, $user); + } + + public function testGetBaseDnNotConfigured() + { + $this->setExpectedException('\LogicException'); + + $user = new User($this->query); + $user->getBasDn(); + } +} diff --git a/tests/units/Core/Ldap/QueryTest.php b/tests/units/Core/Ldap/QueryTest.php new file mode 100644 index 00000000..b3987df0 --- /dev/null +++ b/tests/units/Core/Ldap/QueryTest.php @@ -0,0 +1,160 @@ +<?php + +namespace Kanboard\Core\Ldap; + +require_once __DIR__.'/../../Base.php'; + +function ldap_search($link_identifier, $base_dn, $filter, array $attributes) +{ + return QueryTest::$functions->ldap_search($link_identifier, $base_dn, $filter, $attributes); +} + +function ldap_get_entries($link_identifier, $result_identifier) +{ + return QueryTest::$functions->ldap_get_entries($link_identifier, $result_identifier); +} + +class QueryTest extends \Base +{ + public static $functions; + private $client; + + public function setUp() + { + parent::setup(); + + self::$functions = $this + ->getMockBuilder('stdClass') + ->setMethods(array( + 'ldap_search', + 'ldap_get_entries', + )) + ->getMock(); + + $this->client = $this + ->getMockBuilder('\Kanboard\Core\Ldap\Client') + ->setMethods(array( + 'getConnection', + )) + ->getMock(); + } + + public function tearDown() + { + parent::tearDown(); + self::$functions = null; + } + + public function testExecuteQuerySuccessfully() + { + $entries = array( + 'count' => 1, + 0 => array( + 'count' => 2, + 'dn' => 'uid=my_user,ou=People,dc=kanboard,dc=local', + 'displayname' => array( + 'count' => 1, + 0 => 'My user', + ), + 'mail' => array( + 'count' => 2, + 0 => 'user1@localhost', + 1 => 'user2@localhost', + ), + 0 => 'displayname', + 1 => 'mail', + ) + ); + + $this->client + ->expects($this->any()) + ->method('getConnection') + ->will($this->returnValue('my_ldap_resource')); + + self::$functions + ->expects($this->once()) + ->method('ldap_search') + ->with( + $this->equalTo('my_ldap_resource'), + $this->equalTo('ou=People,dc=kanboard,dc=local'), + $this->equalTo('uid=my_user'), + $this->equalTo(array('displayname')) + ) + ->will($this->returnValue('search_resource')); + + self::$functions + ->expects($this->once()) + ->method('ldap_get_entries') + ->with( + $this->equalTo('my_ldap_resource'), + $this->equalTo('search_resource') + ) + ->will($this->returnValue($entries)); + + $query = new Query($this->client); + $query->execute('ou=People,dc=kanboard,dc=local', 'uid=my_user', array('displayname')); + $this->assertTrue($query->hasResult()); + + $this->assertEquals('My user', $query->getEntries()->getFirstEntry()->getFirstValue('displayname')); + $this->assertEquals('user1@localhost', $query->getEntries()->getFirstEntry()->getFirstValue('mail')); + $this->assertEquals('', $query->getEntries()->getFirstEntry()->getFirstValue('not_found')); + + $this->assertEquals('uid=my_user,ou=People,dc=kanboard,dc=local', $query->getEntries()->getFirstEntry()->getDn()); + $this->assertEquals('', $query->getEntries()->getFirstEntry()->getFirstValue('missing')); + } + + public function testExecuteQueryNotFound() + { + $this->client + ->expects($this->any()) + ->method('getConnection') + ->will($this->returnValue('my_ldap_resource')); + + self::$functions + ->expects($this->once()) + ->method('ldap_search') + ->with( + $this->equalTo('my_ldap_resource'), + $this->equalTo('ou=People,dc=kanboard,dc=local'), + $this->equalTo('uid=my_user'), + $this->equalTo(array('displayname')) + ) + ->will($this->returnValue('search_resource')); + + self::$functions + ->expects($this->once()) + ->method('ldap_get_entries') + ->with( + $this->equalTo('my_ldap_resource'), + $this->equalTo('search_resource') + ) + ->will($this->returnValue(array())); + + $query = new Query($this->client); + $query->execute('ou=People,dc=kanboard,dc=local', 'uid=my_user', array('displayname')); + $this->assertFalse($query->hasResult()); + } + + public function testExecuteQueryFailed() + { + $this->client + ->expects($this->once()) + ->method('getConnection') + ->will($this->returnValue('my_ldap_resource')); + + self::$functions + ->expects($this->once()) + ->method('ldap_search') + ->with( + $this->equalTo('my_ldap_resource'), + $this->equalTo('ou=People,dc=kanboard,dc=local'), + $this->equalTo('uid=my_user'), + $this->equalTo(array('displayname')) + ) + ->will($this->returnValue(false)); + + $query = new Query($this->client); + $query->execute('ou=People,dc=kanboard,dc=local', 'uid=my_user', array('displayname')); + $this->assertFalse($query->hasResult()); + } +} diff --git a/tests/units/Core/LexerTest.php b/tests/units/Core/LexerTest.php index 9e14ff6b..55370aab 100644 --- a/tests/units/Core/LexerTest.php +++ b/tests/units/Core/LexerTest.php @@ -116,6 +116,31 @@ class LexerTest extends Base ); } + public function testLinkQuery() + { + $lexer = new Lexer; + + $this->assertEquals( + array(array('match' => 'link:', 'token' => 'T_LINK'), array('match' => 'is a milestone of', 'token' => 'T_STRING')), + $lexer->tokenize('link:"is a milestone of"') + ); + + $this->assertEquals( + array('T_LINK' => array('is a milestone of')), + $lexer->map($lexer->tokenize('link:"is a milestone of"')) + ); + + $this->assertEquals( + array('T_LINK' => array('is a milestone of', 'fixes')), + $lexer->map($lexer->tokenize('link:"is a milestone of" link:fixes')) + ); + + $this->assertEquals( + array(), + $lexer->map($lexer->tokenize('link: ')) + ); + } + public function testColumnQuery() { $lexer = new Lexer; diff --git a/tests/units/Core/RouterTest.php b/tests/units/Core/RouterTest.php deleted file mode 100644 index 753e1204..00000000 --- a/tests/units/Core/RouterTest.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php - -require_once __DIR__.'/../Base.php'; - -use Kanboard\Core\Router; - -class RouterTest extends Base -{ - public function testSanitize() - { - $r = new Router($this->container); - - $this->assertEquals('PloP', $r->sanitize('PloP', 'default')); - $this->assertEquals('default', $r->sanitize('', 'default')); - $this->assertEquals('default', $r->sanitize('123-AB', 'default')); - $this->assertEquals('default', $r->sanitize('R&D', 'default')); - $this->assertEquals('Test123', $r->sanitize('Test123', 'default')); - $this->assertEquals('Test_123', $r->sanitize('Test_123', 'default')); - $this->assertEquals('userImport', $r->sanitize('userImport', 'default')); - } - - public function testPath() - { - $r = new Router($this->container); - - $this->assertEquals('a/b/c', $r->getPath('/a/b/c')); - $this->assertEquals('a/b/something', $r->getPath('/a/b/something?test=a', 'test=a')); - - $_SERVER['REQUEST_METHOD'] = 'GET'; - $_SERVER['PHP_SELF'] = '/a/index.php'; - - $this->assertEquals('b/c', $r->getPath('/a/b/c')); - $this->assertEquals('b/c', $r->getPath('/a/b/c?e=f', 'e=f')); - } - - public function testFindRouteWithEmptyTable() - { - $r = new Router($this->container); - $this->assertEquals(array('app', 'index'), $r->findRoute('')); - $this->assertEquals(array('app', 'index'), $r->findRoute('/')); - } - - public function testFindRouteWithoutPlaceholders() - { - $r = new Router($this->container); - $r->addRoute('a/b', 'controller', 'action'); - $this->assertEquals(array('app', 'index'), $r->findRoute('a/b/c')); - $this->assertEquals(array('controller', 'action'), $r->findRoute('a/b')); - } - - public function testFindRouteWithPlaceholders() - { - $r = new Router($this->container); - $r->addRoute('a/:myvar1/b/:myvar2', 'controller', 'action'); - $this->assertEquals(array('app', 'index'), $r->findRoute('a/123/b')); - $this->assertEquals(array('controller', 'action'), $r->findRoute('a/456/b/789')); - $this->assertEquals(array('myvar1' => 456, 'myvar2' => 789), $_GET); - } - - public function testFindMultipleRoutes() - { - $r = new Router($this->container); - $r->addRoute('a/b', 'controller1', 'action1'); - $r->addRoute('a/b', 'duplicate', 'duplicate'); - $r->addRoute('a', 'controller2', 'action2'); - $this->assertEquals(array('controller1', 'action1'), $r->findRoute('a/b')); - $this->assertEquals(array('controller2', 'action2'), $r->findRoute('a')); - } - - public function testFindUrl() - { - $r = new Router($this->container); - $r->addRoute('a/b', 'controller1', 'action1'); - $r->addRoute('a/:myvar1/b/:myvar2', 'controller2', 'action2', array('myvar1', 'myvar2')); - - $this->assertEquals('a/1/b/2', $r->findUrl('controller2', 'action2', array('myvar1' => 1, 'myvar2' => 2))); - $this->assertEquals('', $r->findUrl('controller2', 'action2', array('myvar1' => 1))); - $this->assertEquals('a/b', $r->findUrl('controller1', 'action1')); - $this->assertEquals('', $r->findUrl('controller1', 'action2')); - } -} diff --git a/tests/units/Core/Security/AccessMapTest.php b/tests/units/Core/Security/AccessMapTest.php new file mode 100644 index 00000000..ae8044c9 --- /dev/null +++ b/tests/units/Core/Security/AccessMapTest.php @@ -0,0 +1,53 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Security\AccessMap; + +class AccessMapTest extends Base +{ + public function testRoleHierarchy() + { + $acl = new AccessMap; + $acl->setRoleHierarchy('admin', array('manager', 'user')); + $acl->setRoleHierarchy('manager', array('user')); + + $this->assertEquals(array('admin'), $acl->getRoleHierarchy('admin')); + $this->assertEquals(array('manager', 'admin'), $acl->getRoleHierarchy('manager')); + $this->assertEquals(array('user', 'admin', 'manager'), $acl->getRoleHierarchy('user')); + } + + public function testGetHighestRole() + { + $acl = new AccessMap; + $acl->setRoleHierarchy('manager', array('member', 'viewer')); + $acl->setRoleHierarchy('member', array('viewer')); + + $this->assertEquals('manager', $acl->getHighestRole(array('viewer', 'manager', 'member'))); + $this->assertEquals('manager', $acl->getHighestRole(array('viewer', 'manager'))); + $this->assertEquals('manager', $acl->getHighestRole(array('manager', 'member'))); + $this->assertEquals('member', $acl->getHighestRole(array('viewer', 'member'))); + $this->assertEquals('member', $acl->getHighestRole(array('member'))); + $this->assertEquals('viewer', $acl->getHighestRole(array('viewer'))); + } + + public function testAddRulesAndGetRoles() + { + $acl = new AccessMap; + $acl->setDefaultRole('role3'); + $acl->setRoleHierarchy('role2', array('role1')); + + $acl->add('MyController', 'myAction1', 'role2'); + $acl->add('MyController', 'myAction2', 'role1'); + $acl->add('MyAdminController', '*', 'role2'); + $acl->add('SomethingElse', array('actionA', 'actionB'), 'role2'); + + $this->assertEquals(array('role2'), $acl->getRoles('mycontroller', 'MyAction1')); + $this->assertEquals(array('role1', 'role2'), $acl->getRoles('mycontroller', 'MyAction2')); + $this->assertEquals(array('role2'), $acl->getRoles('Myadmincontroller', 'MyAction')); + $this->assertEquals(array('role3'), $acl->getRoles('AnotherController', 'ActionNotFound')); + $this->assertEquals(array('role2'), $acl->getRoles('somethingelse', 'actiona')); + $this->assertEquals(array('role2'), $acl->getRoles('somethingelse', 'actionb')); + $this->assertEquals(array('role3'), $acl->getRoles('somethingelse', 'actionc')); + } +} diff --git a/tests/units/Core/Security/AuthenticationManagerTest.php b/tests/units/Core/Security/AuthenticationManagerTest.php new file mode 100644 index 00000000..c2369626 --- /dev/null +++ b/tests/units/Core/Security/AuthenticationManagerTest.php @@ -0,0 +1,150 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Http\Request; +use Kanboard\Core\Security\AuthenticationManager; +use Kanboard\Auth\DatabaseAuth; +use Kanboard\Auth\TotpAuth; +use Kanboard\Auth\ReverseProxyAuth; + +class AuthenticationManagerTest extends Base +{ + public function testRegister() + { + $authManager = new AuthenticationManager($this->container); + $authManager->register(new DatabaseAuth($this->container)); + $provider = $authManager->getProvider('Database'); + + $this->assertInstanceOf('Kanboard\Core\Security\AuthenticationProviderInterface', $provider); + } + + public function testGetProviderNotFound() + { + $authManager = new AuthenticationManager($this->container); + $this->setExpectedException('LogicException'); + $authManager->getProvider('Dababase'); + } + + public function testGetPostProviderNotFound() + { + $authManager = new AuthenticationManager($this->container); + $this->setExpectedException('LogicException'); + $authManager->getPostAuthenticationProvider(); + } + + public function testGetPostProvider() + { + $authManager = new AuthenticationManager($this->container); + $authManager->register(new TotpAuth($this->container)); + $provider = $authManager->getPostAuthenticationProvider(); + + $this->assertInstanceOf('Kanboard\Core\Security\PostAuthenticationProviderInterface', $provider); + } + + public function testCheckSessionWhenNobodyIsLogged() + { + $authManager = new AuthenticationManager($this->container); + $authManager->register(new DatabaseAuth($this->container)); + + $this->assertFalse($this->container['userSession']->isLogged()); + $this->assertTrue($authManager->checkCurrentSession()); + } + + public function testCheckSessionWhenSomeoneIsLogged() + { + $authManager = new AuthenticationManager($this->container); + $authManager->register(new DatabaseAuth($this->container)); + + $this->container['sessionStorage']->user = array('id' => 1); + + $this->assertTrue($this->container['userSession']->isLogged()); + $this->assertTrue($authManager->checkCurrentSession()); + } + + public function testCheckSessionWhenNotValid() + { + $authManager = new AuthenticationManager($this->container); + $authManager->register(new DatabaseAuth($this->container)); + + $this->container['sessionStorage']->user = array('id' => 2); + + $this->assertTrue($this->container['userSession']->isLogged()); + $this->assertFalse($authManager->checkCurrentSession()); + $this->assertFalse($this->container['userSession']->isLogged()); + } + + public function testPreAuthenticationSuccessful() + { + $this->container['request'] = new Request($this->container, array(REVERSE_PROXY_USER_HEADER => 'admin')); + $this->container['dispatcher']->addListener(AuthenticationManager::EVENT_SUCCESS, array($this, 'onSuccess')); + $this->container['dispatcher']->addListener(AuthenticationManager::EVENT_FAILURE, array($this, 'onFailure')); + + $authManager = new AuthenticationManager($this->container); + $authManager->register(new ReverseProxyAuth($this->container)); + + $this->assertTrue($authManager->preAuthentication()); + + $called = $this->container['dispatcher']->getCalledListeners(); + $this->assertArrayHasKey(AuthenticationManager::EVENT_SUCCESS.'.AuthenticationManagerTest::onSuccess', $called); + $this->assertArrayNotHasKey(AuthenticationManager::EVENT_FAILURE.'.AuthenticationManagerTest::onFailure', $called); + } + + public function testPreAuthenticationFailed() + { + $this->container['request'] = new Request($this->container, array(REVERSE_PROXY_USER_HEADER => '')); + $this->container['dispatcher']->addListener(AuthenticationManager::EVENT_SUCCESS, array($this, 'onSuccess')); + $this->container['dispatcher']->addListener(AuthenticationManager::EVENT_FAILURE, array($this, 'onFailure')); + + $authManager = new AuthenticationManager($this->container); + $authManager->register(new ReverseProxyAuth($this->container)); + + $this->assertFalse($authManager->preAuthentication()); + + $called = $this->container['dispatcher']->getCalledListeners(); + $this->assertArrayNotHasKey(AuthenticationManager::EVENT_SUCCESS.'.AuthenticationManagerTest::onSuccess', $called); + $this->assertArrayNotHasKey(AuthenticationManager::EVENT_FAILURE.'.AuthenticationManagerTest::onFailure', $called); + } + + public function testPasswordAuthenticationSuccessful() + { + $this->container['dispatcher']->addListener(AuthenticationManager::EVENT_SUCCESS, array($this, 'onSuccess')); + $this->container['dispatcher']->addListener(AuthenticationManager::EVENT_FAILURE, array($this, 'onFailure')); + + $authManager = new AuthenticationManager($this->container); + $authManager->register(new DatabaseAuth($this->container)); + + $this->assertTrue($authManager->passwordAuthentication('admin', 'admin')); + + $called = $this->container['dispatcher']->getCalledListeners(); + $this->assertArrayHasKey(AuthenticationManager::EVENT_SUCCESS.'.AuthenticationManagerTest::onSuccess', $called); + $this->assertArrayNotHasKey(AuthenticationManager::EVENT_FAILURE.'.AuthenticationManagerTest::onFailure', $called); + } + + public function testPasswordAuthenticationFailed() + { + $this->container['dispatcher']->addListener(AuthenticationManager::EVENT_SUCCESS, array($this, 'onSuccess')); + $this->container['dispatcher']->addListener(AuthenticationManager::EVENT_FAILURE, array($this, 'onFailure')); + + $authManager = new AuthenticationManager($this->container); + $authManager->register(new DatabaseAuth($this->container)); + + $this->assertFalse($authManager->passwordAuthentication('admin', 'wrong password')); + + $called = $this->container['dispatcher']->getCalledListeners(); + $this->assertArrayNotHasKey(AuthenticationManager::EVENT_SUCCESS.'.AuthenticationManagerTest::onSuccess', $called); + $this->assertArrayHasKey(AuthenticationManager::EVENT_FAILURE.'.AuthenticationManagerTest::onFailure', $called); + } + + public function onSuccess($event) + { + $this->assertInstanceOf('Kanboard\Event\AuthSuccessEvent', $event); + $this->assertTrue(in_array($event->getAuthType(), array('Database', 'ReverseProxy'))); + } + + public function onFailure($event) + { + $this->assertInstanceOf('Kanboard\Event\AuthFailureEvent', $event); + $this->assertEquals('admin', $event->getUsername()); + } +} diff --git a/tests/units/Core/Security/AuthorizationTest.php b/tests/units/Core/Security/AuthorizationTest.php new file mode 100644 index 00000000..70561ad8 --- /dev/null +++ b/tests/units/Core/Security/AuthorizationTest.php @@ -0,0 +1,39 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Security\Role; +use Kanboard\Core\Security\AccessMap; +use Kanboard\Core\Security\Authorization; + +class AuthorizationTest extends Base +{ + public function testIsAllowed() + { + $acl = new AccessMap; + $acl->setDefaultRole(Role::APP_USER); + $acl->setRoleHierarchy(Role::APP_ADMIN, array(Role::APP_MANAGER, Role::APP_USER)); + $acl->setRoleHierarchy(Role::APP_MANAGER, array(Role::APP_USER)); + + $acl->add('MyController', 'myAction1', Role::APP_MANAGER); + $acl->add('MyController', 'myAction2', Role::APP_ADMIN); + $acl->add('MyManagerController', '*', Role::APP_MANAGER); + + $authorization = new Authorization($acl); + + $this->assertTrue($authorization->isAllowed('myController', 'myAction1', Role::APP_ADMIN)); + $this->assertTrue($authorization->isAllowed('myController', 'myAction1', Role::APP_MANAGER)); + $this->assertFalse($authorization->isAllowed('myController', 'myAction1', Role::APP_USER)); + $this->assertFalse($authorization->isAllowed('myController', 'myAction1', 'something else')); + + $this->assertTrue($authorization->isAllowed('MyManagerController', 'myAction', Role::APP_ADMIN)); + $this->assertTrue($authorization->isAllowed('MyManagerController', 'myAction', Role::APP_MANAGER)); + $this->assertFalse($authorization->isAllowed('MyManagerController', 'myAction', Role::APP_USER)); + $this->assertFalse($authorization->isAllowed('MyManagerController', 'myAction', 'something else')); + + $this->assertTrue($authorization->isAllowed('MyUserController', 'myAction', Role::APP_ADMIN)); + $this->assertTrue($authorization->isAllowed('MyUserController', 'myAction', Role::APP_MANAGER)); + $this->assertTrue($authorization->isAllowed('MyUserController', 'myAction', Role::APP_USER)); + $this->assertFalse($authorization->isAllowed('MyUserController', 'myAction', 'something else')); + } +} diff --git a/tests/units/Core/Security/TokenTest.php b/tests/units/Core/Security/TokenTest.php new file mode 100644 index 00000000..dbb7bd1a --- /dev/null +++ b/tests/units/Core/Security/TokenTest.php @@ -0,0 +1,29 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Security\Token; + +class TokenTest extends Base +{ + public function testGenerateToken() + { + $t1 = Token::getToken(); + $t2 = Token::getToken(); + + $this->assertNotEmpty($t1); + $this->assertNotEmpty($t2); + + $this->assertNotEquals($t1, $t2); + } + + public function testCSRFTokens() + { + $token = new Token($this->container); + $t1 = $token->getCSRFToken(); + + $this->assertNotEmpty($t1); + $this->assertTrue($token->validateCSRFToken($t1)); + $this->assertFalse($token->validateCSRFToken($t1)); + } +} diff --git a/tests/units/Core/Session/FlashMessageTest.php b/tests/units/Core/Session/FlashMessageTest.php new file mode 100644 index 00000000..25361343 --- /dev/null +++ b/tests/units/Core/Session/FlashMessageTest.php @@ -0,0 +1,23 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Session\FlashMessage; + +class FlashMessageTest extends Base +{ + public function testMessage() + { + $flash = new FlashMessage($this->container); + + $flash->success('my message'); + $this->assertEquals('my message', $flash->getMessage('success')); + $this->assertEmpty($flash->getMessage('success')); + + $flash->failure('my error message'); + $this->assertEquals('my error message', $flash->getMessage('failure')); + $this->assertEmpty($flash->getMessage('failure')); + + $this->assertEmpty($flash->getMessage('not found')); + } +} diff --git a/tests/units/Core/Session/SessionStorageTest.php b/tests/units/Core/Session/SessionStorageTest.php new file mode 100644 index 00000000..dd0040d5 --- /dev/null +++ b/tests/units/Core/Session/SessionStorageTest.php @@ -0,0 +1,60 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Session\SessionStorage; + +class SessionStorageTest extends Base +{ + public function testNotPersistentStorage() + { + $storage = new SessionStorage(); + $storage->something = array('a' => 'b'); + $this->assertEquals(array('a' => 'b'), $storage->something); + $this->assertTrue(isset($storage->something)); + $this->assertFalse(isset($storage->something->x)); + $this->assertFalse(isset($storage->notFound)); + $this->assertFalse(isset($storage->notFound->x)); + $this->assertFalse(isset($storage->notFound['x'])); + } + + public function testPersistentStorage() + { + $session = array('d' => 'e'); + + $storage = new SessionStorage(); + $storage->setStorage($session); + $storage->something = array('a' => 'b'); + + $this->assertEquals(array('a' => 'b'), $storage->something); + $this->assertEquals('e', $storage->d); + + $storage->something['a'] = 'c'; + $this->assertEquals('c', $storage->something['a']); + + $storage = null; + $this->assertEquals(array('something' => array('a' => 'c'), 'd' => 'e'), $session); + } + + public function testFlush() + { + $session = array('d' => 'e'); + + $storage = new SessionStorage(); + $storage->setStorage($session); + $storage->something = array('a' => 'b'); + + $this->assertEquals(array('a' => 'b'), $storage->something); + $this->assertEquals('e', $storage->d); + + $storage->flush(); + + $this->assertFalse(isset($storage->d)); + $this->assertFalse(isset($storage->something)); + + $storage->foo = 'bar'; + + $storage = null; + $this->assertEquals(array('foo' => 'bar'), $session); + } +} diff --git a/tests/units/Core/User/GroupSyncTest.php b/tests/units/Core/User/GroupSyncTest.php new file mode 100644 index 00000000..e22b86d4 --- /dev/null +++ b/tests/units/Core/User/GroupSyncTest.php @@ -0,0 +1,30 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\User\GroupSync; +use Kanboard\Model\Group; +use Kanboard\Model\GroupMember; + +class GroupSyncTest extends Base +{ + public function testSynchronize() + { + $group = new Group($this->container); + $groupMember = new GroupMember($this->container); + $groupSync = new GroupSync($this->container); + + $this->assertEquals(1, $group->create('My Group 1', 'externalId1')); + $this->assertEquals(2, $group->create('My Group 2', 'externalId2')); + + $this->assertTrue($groupMember->addUser(1, 1)); + + $this->assertTrue($groupMember->isMember(1, 1)); + $this->assertFalse($groupMember->isMember(2, 1)); + + $groupSync->synchronize(1, array('externalId1', 'externalId2', 'externalId3')); + + $this->assertTrue($groupMember->isMember(1, 1)); + $this->assertTrue($groupMember->isMember(2, 1)); + } +} diff --git a/tests/units/Core/User/UserProfileTest.php b/tests/units/Core/User/UserProfileTest.php new file mode 100644 index 00000000..4886a945 --- /dev/null +++ b/tests/units/Core/User/UserProfileTest.php @@ -0,0 +1,63 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Security\Role; +use Kanboard\Core\User\UserProfile; +use Kanboard\User\LdapUserProvider; +use Kanboard\User\DatabaseUserProvider; + +class UserProfileTest extends Base +{ + public function testInitializeLocalUser() + { + $userProfile = new UserProfile($this->container); + $user = new DatabaseUserProvider(array('id' => 1)); + + $this->assertTrue($userProfile->initialize($user)); + $this->assertNotEmpty($this->container['sessionStorage']->user); + $this->assertEquals('admin', $this->container['sessionStorage']->user['username']); + } + + public function testInitializeLocalUserNotFound() + { + $userProfile = new UserProfile($this->container); + $user = new DatabaseUserProvider(array('id' => 2)); + + $this->assertFalse($userProfile->initialize($user)); + $this->assertFalse(isset($this->container['sessionStorage']->user)); + } + + public function testInitializeRemoteUser() + { + $userProfile = new UserProfile($this->container); + $user = new LdapUserProvider('ldapId', 'bob', 'Bob', '', Role::APP_MANAGER, array()); + + $this->assertTrue($userProfile->initialize($user)); + $this->assertNotEmpty($this->container['sessionStorage']->user); + $this->assertEquals(2, $this->container['sessionStorage']->user['id']); + $this->assertEquals('bob', $this->container['sessionStorage']->user['username']); + $this->assertEquals(Role::APP_MANAGER, $this->container['sessionStorage']->user['role']); + + $user = new LdapUserProvider('ldapId', 'bob', 'Bob', '', Role::APP_MANAGER, array()); + + $this->assertTrue($userProfile->initialize($user)); + $this->assertNotEmpty($this->container['sessionStorage']->user); + $this->assertEquals(2, $this->container['sessionStorage']->user['id']); + $this->assertEquals('bob', $this->container['sessionStorage']->user['username']); + } + + public function testAssignRemoteUser() + { + $userProfile = new UserProfile($this->container); + $user = new LdapUserProvider('ldapId', 'bob', 'Bob', '', Role::APP_MANAGER, array()); + + $this->assertTrue($userProfile->assign(1, $user)); + $this->assertNotEmpty($this->container['sessionStorage']->user); + $this->assertEquals(1, $this->container['sessionStorage']->user['id']); + $this->assertEquals('admin', $this->container['sessionStorage']->user['username']); + $this->assertEquals('Bob', $this->container['sessionStorage']->user['name']); + $this->assertEquals('', $this->container['sessionStorage']->user['email']); + $this->assertEquals(Role::APP_ADMIN, $this->container['sessionStorage']->user['role']); + } +} diff --git a/tests/units/Core/User/UserPropertyTest.php b/tests/units/Core/User/UserPropertyTest.php new file mode 100644 index 00000000..170eab4c --- /dev/null +++ b/tests/units/Core/User/UserPropertyTest.php @@ -0,0 +1,60 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Security\Role; +use Kanboard\Core\User\UserProperty; +use Kanboard\User\LdapUserProvider; + +class UserPropertyTest extends Base +{ + public function testGetProperties() + { + $user = new LdapUserProvider('ldapId', 'bob', 'Bob', '', Role::APP_USER, array()); + + $expected = array( + 'username' => 'bob', + 'name' => 'Bob', + 'role' => Role::APP_USER, + 'is_ldap_user' => 1, + ); + + $this->assertEquals($expected, UserProperty::getProperties($user)); + + $user = new LdapUserProvider('ldapId', 'bob', '', '', '', array()); + + $expected = array( + 'username' => 'bob', + 'is_ldap_user' => 1, + ); + + $this->assertEquals($expected, UserProperty::getProperties($user)); + } + + public function testFilterProperties() + { + $profile = array( + 'id' => 123, + 'username' => 'bob', + 'name' => null, + 'email' => '', + 'other_column' => 'myvalue', + 'role' => Role::APP_ADMIN, + ); + + $properties = array( + 'external_id' => '456', + 'username' => 'bobby', + 'name' => 'Bobby', + 'email' => 'admin@localhost', + 'role' => '', + ); + + $expected = array( + 'name' => 'Bobby', + 'email' => 'admin@localhost', + ); + + $this->assertEquals($expected, UserProperty::filterProperties($profile, $properties)); + } +} diff --git a/tests/units/Core/User/UserSessionTest.php b/tests/units/Core/User/UserSessionTest.php new file mode 100644 index 00000000..64413f98 --- /dev/null +++ b/tests/units/Core/User/UserSessionTest.php @@ -0,0 +1,144 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\User\UserSession; +use Kanboard\Core\Security\Role; + +class UserSessionTest extends Base +{ + public function testInitialize() + { + $us = new UserSession($this->container); + + $user = array( + 'id' => '123', + 'username' => 'john', + 'password' => 'something', + 'twofactor_secret' => 'something else', + 'is_admin' => '1', + 'is_project_admin' => '0', + 'is_ldap_user' => '0', + 'twofactor_activated' => '0', + 'role' => Role::APP_MANAGER, + ); + + $us->initialize($user); + + $session = $this->container['sessionStorage']->getAll(); + + $this->assertNotEmpty($session); + $this->assertEquals(123, $session['user']['id']); + $this->assertEquals('john', $session['user']['username']); + $this->assertEquals(Role::APP_MANAGER, $session['user']['role']); + $this->assertFalse($session['user']['is_ldap_user']); + $this->assertFalse($session['user']['twofactor_activated']); + $this->assertArrayNotHasKey('password', $session['user']); + $this->assertArrayNotHasKey('twofactor_secret', $session['user']); + $this->assertArrayNotHasKey('is_admin', $session['user']); + $this->assertArrayNotHasKey('is_project_admin', $session['user']); + + $this->assertEquals('john', $us->getUsername()); + } + + public function testGetId() + { + $us = new UserSession($this->container); + + $this->assertEquals(0, $us->getId()); + + $this->container['sessionStorage']->user = array('id' => 2); + $this->assertEquals(2, $us->getId()); + + $this->container['sessionStorage']->user = array('id' => '2'); + $this->assertEquals(2, $us->getId()); + } + + public function testIsLogged() + { + $us = new UserSession($this->container); + + $this->assertFalse($us->isLogged()); + + $this->container['sessionStorage']->user = array(); + $this->assertFalse($us->isLogged()); + + $this->container['sessionStorage']->user = array('id' => 1); + $this->assertTrue($us->isLogged()); + } + + public function testIsAdmin() + { + $us = new UserSession($this->container); + + $this->assertFalse($us->isAdmin()); + + $this->container['sessionStorage']->user = array('role' => Role::APP_ADMIN); + $this->assertTrue($us->isAdmin()); + + $this->container['sessionStorage']->user = array('role' => Role::APP_USER); + $this->assertFalse($us->isAdmin()); + + $this->container['sessionStorage']->user = array('role' => ''); + $this->assertFalse($us->isAdmin()); + } + + public function testCommentSorting() + { + $us = new UserSession($this->container); + $this->assertEquals('ASC', $us->getCommentSorting()); + + $us->setCommentSorting('DESC'); + $this->assertEquals('DESC', $us->getCommentSorting()); + } + + public function testBoardCollapseMode() + { + $us = new UserSession($this->container); + $this->assertFalse($us->isBoardCollapsed(2)); + + $us->setBoardDisplayMode(3, false); + $this->assertFalse($us->isBoardCollapsed(3)); + + $us->setBoardDisplayMode(3, true); + $this->assertTrue($us->isBoardCollapsed(3)); + } + + public function testFilters() + { + $us = new UserSession($this->container); + $this->assertEquals('status:open', $us->getFilters(1)); + + $us->setFilters(1, 'assignee:me'); + $this->assertEquals('assignee:me', $us->getFilters(1)); + + $this->assertEquals('status:open', $us->getFilters(2)); + + $us->setFilters(2, 'assignee:bob'); + $this->assertEquals('assignee:bob', $us->getFilters(2)); + } + + public function testPostAuthentication() + { + $us = new UserSession($this->container); + $this->assertFalse($us->isPostAuthenticationValidated()); + + $this->container['sessionStorage']->postAuthenticationValidated = false; + $this->assertFalse($us->isPostAuthenticationValidated()); + + $us->validatePostAuthentication(); + $this->assertTrue($us->isPostAuthenticationValidated()); + + $this->container['sessionStorage']->user = array(); + $this->assertFalse($us->hasPostAuthentication()); + + $this->container['sessionStorage']->user = array('twofactor_activated' => false); + $this->assertFalse($us->hasPostAuthentication()); + + $this->container['sessionStorage']->user = array('twofactor_activated' => true); + $this->assertTrue($us->hasPostAuthentication()); + + $us->disablePostAuthentication(); + $this->assertFalse($us->hasPostAuthentication()); + } +} diff --git a/tests/units/Core/User/UserSyncTest.php b/tests/units/Core/User/UserSyncTest.php new file mode 100644 index 00000000..e7ce42b2 --- /dev/null +++ b/tests/units/Core/User/UserSyncTest.php @@ -0,0 +1,55 @@ +<?php + +require_once __DIR__.'/../../Base.php'; + +use Kanboard\Core\Security\Role; +use Kanboard\Core\User\UserSync; +use Kanboard\User\LdapUserProvider; + +class UserSyncTest extends Base +{ + public function testSynchronizeNewUser() + { + $user = new LdapUserProvider('ldapId', 'bob', 'Bob', '', Role::APP_MANAGER, array()); + $userSync = new UserSync($this->container); + + $profile = array( + 'id' => 2, + 'username' => 'bob', + 'name' => 'Bob', + 'email' => '', + 'role' => Role::APP_MANAGER, + 'is_ldap_user' => 1, + ); + + $this->assertArraySubset($profile, $userSync->synchronize($user)); + } + + public function testSynchronizeExistingUser() + { + $userSync = new UserSync($this->container); + $user = new LdapUserProvider('ldapId', 'admin', 'Admin', 'email@localhost', Role::APP_MANAGER, array()); + + $profile = array( + 'id' => 1, + 'username' => 'admin', + 'name' => 'Admin', + 'email' => 'email@localhost', + 'role' => Role::APP_MANAGER, + ); + + $this->assertArraySubset($profile, $userSync->synchronize($user)); + + $user = new LdapUserProvider('ldapId', 'admin', '', '', Role::APP_ADMIN, array()); + + $profile = array( + 'id' => 1, + 'username' => 'admin', + 'name' => 'Admin', + 'email' => 'email@localhost', + 'role' => Role::APP_ADMIN, + ); + + $this->assertArraySubset($profile, $userSync->synchronize($user)); + } +} |