mirror of
https://github.com/kevinpapst/kimai2.git
synced 2025-03-17 14:32:38 +00:00
added some more tests (#1835)
This commit is contained in:
parent
aee063bb3c
commit
4b8f743fa6
7 changed files with 175 additions and 5 deletions
src/Doctrine
tests
Export/Spreadsheet
Mocks/Saml
Saml
Utils
|
@ -18,6 +18,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all Doctrine migrations.
|
* Base class for all Doctrine migrations.
|
||||||
|
*
|
||||||
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
abstract class AbstractMigration extends BaseAbstractMigration implements ContainerAwareInterface
|
abstract class AbstractMigration extends BaseAbstractMigration implements ContainerAwareInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace App\Tests\Export\Spreadsheet;
|
||||||
|
|
||||||
use App\Entity\Customer;
|
use App\Entity\Customer;
|
||||||
use App\Entity\Project;
|
use App\Entity\Project;
|
||||||
|
use App\Entity\ProjectMeta;
|
||||||
use App\Event\ProjectMetaDisplayEvent;
|
use App\Event\ProjectMetaDisplayEvent;
|
||||||
use App\Export\Spreadsheet\EntityWithMetaFieldsExporter;
|
use App\Export\Spreadsheet\EntityWithMetaFieldsExporter;
|
||||||
use App\Export\Spreadsheet\Extractor\AnnotationExtractor;
|
use App\Export\Spreadsheet\Extractor\AnnotationExtractor;
|
||||||
|
@ -29,9 +30,16 @@ class EntityWithMetaFieldsExporterTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testExport()
|
public function testExport()
|
||||||
{
|
{
|
||||||
|
$dispatcher = $this->createMock(EventDispatcherInterface::class);
|
||||||
|
$dispatcher->expects(self::once())->method('dispatch')->willReturnCallback(function (ProjectMetaDisplayEvent $event) {
|
||||||
|
$event->addField((new ProjectMeta())->setName('foo meta')->setIsVisible(true));
|
||||||
|
$event->addField((new ProjectMeta())->setName('hidden meta')->setIsVisible(false));
|
||||||
|
$event->addField((new ProjectMeta())->setName('bar meta')->setIsVisible(true));
|
||||||
|
});
|
||||||
|
|
||||||
$spreadsheetExporter = new SpreadsheetExporter($this->createMock(TranslatorInterface::class));
|
$spreadsheetExporter = new SpreadsheetExporter($this->createMock(TranslatorInterface::class));
|
||||||
$annotationExtractor = new AnnotationExtractor(new AnnotationReader());
|
$annotationExtractor = new AnnotationExtractor(new AnnotationReader());
|
||||||
$metaFieldExtractor = new MetaFieldExtractor($this->createMock(EventDispatcherInterface::class));
|
$metaFieldExtractor = new MetaFieldExtractor($dispatcher);
|
||||||
|
|
||||||
$project = new Project();
|
$project = new Project();
|
||||||
$project->setName('test project');
|
$project->setName('test project');
|
||||||
|
@ -42,6 +50,9 @@ class EntityWithMetaFieldsExporterTest extends TestCase
|
||||||
$project->setTimeBudget(1234567890);
|
$project->setTimeBudget(1234567890);
|
||||||
$project->setColor('#ababab');
|
$project->setColor('#ababab');
|
||||||
$project->setVisible(false);
|
$project->setVisible(false);
|
||||||
|
$project->setMetaField((new ProjectMeta())->setName('foo meta')->setValue('some magic')->setIsVisible(true));
|
||||||
|
$project->setMetaField((new ProjectMeta())->setName('hidden meta')->setValue('will not be seen')->setIsVisible(false));
|
||||||
|
$project->setMetaField((new ProjectMeta())->setName('bar meta')->setValue('is happening')->setIsVisible(true));
|
||||||
|
|
||||||
$sut = new EntityWithMetaFieldsExporter($spreadsheetExporter, $annotationExtractor, $metaFieldExtractor);
|
$sut = new EntityWithMetaFieldsExporter($spreadsheetExporter, $annotationExtractor, $metaFieldExtractor);
|
||||||
$spreadsheet = $sut->export(Project::class, [$project], new ProjectMetaDisplayEvent(new ProjectQuery(), ProjectMetaDisplayEvent::EXPORT));
|
$spreadsheet = $sut->export(Project::class, [$project], new ProjectMetaDisplayEvent(new ProjectQuery(), ProjectMetaDisplayEvent::EXPORT));
|
||||||
|
@ -57,5 +68,7 @@ class EntityWithMetaFieldsExporterTest extends TestCase
|
||||||
self::assertEquals('#ababab', $worksheet->getCellByColumnAndRow(8, 2, false)->getValue());
|
self::assertEquals('#ababab', $worksheet->getCellByColumnAndRow(8, 2, false)->getValue());
|
||||||
self::assertFalse($worksheet->getCellByColumnAndRow(9, 2, false)->getValue());
|
self::assertFalse($worksheet->getCellByColumnAndRow(9, 2, false)->getValue());
|
||||||
self::assertEquals('Lorem Ipsum', $worksheet->getCellByColumnAndRow(10, 2, false)->getValue());
|
self::assertEquals('Lorem Ipsum', $worksheet->getCellByColumnAndRow(10, 2, false)->getValue());
|
||||||
|
self::assertEquals('some magic', $worksheet->getCellByColumnAndRow(11, 2, false)->getValue());
|
||||||
|
self::assertEquals('is happening', $worksheet->getCellByColumnAndRow(12, 2, false)->getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ use Symfony\Component\HttpFoundation\RequestStack;
|
||||||
|
|
||||||
class SamlAuthFactory extends AbstractMockFactory
|
class SamlAuthFactory extends AbstractMockFactory
|
||||||
{
|
{
|
||||||
public function create(?array $connection = null): SamlAuth
|
public function create(?array $connection = null, bool $fromTrustedProxy = false): SamlAuth
|
||||||
{
|
{
|
||||||
if (null === $connection) {
|
if (null === $connection) {
|
||||||
$connection = [
|
$connection = [
|
||||||
|
@ -76,8 +76,11 @@ class SamlAuthFactory extends AbstractMockFactory
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$request = $this->getMockBuilder(Request::class)->getMock();
|
||||||
|
$request->method('isFromTrustedProxy')->willReturn($fromTrustedProxy);
|
||||||
|
|
||||||
$requestStack = new RequestStack();
|
$requestStack = new RequestStack();
|
||||||
$requestStack->push(new Request());
|
$requestStack->push($request);
|
||||||
|
|
||||||
return new SamlAuth($requestStack, $connection);
|
return new SamlAuth($requestStack, $connection);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,11 @@ namespace App\Tests\Saml\Controller;
|
||||||
use App\Saml\Controller\SamlController;
|
use App\Saml\Controller\SamlController;
|
||||||
use App\Tests\Mocks\Saml\SamlAuthFactory;
|
use App\Tests\Mocks\Saml\SamlAuthFactory;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use PHPUnit\Util\Xml;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\HttpFoundation\Session\SessionInterface;
|
||||||
|
use Symfony\Component\Security\Core\Security;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @group integration
|
* @group integration
|
||||||
|
@ -42,4 +47,58 @@ class SamlControllerTest extends TestCase
|
||||||
$sut = new SamlController($oauth);
|
$sut = new SamlController($oauth);
|
||||||
$sut->logoutAction();
|
$sut->logoutAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testMetadataAction()
|
||||||
|
{
|
||||||
|
$expected = <<<EOD
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" validUntil="2020-07-23T10:26:50Z" cacheDuration="PT604800S" entityID="https://127.0.0.1:8010/auth/saml/metadata">
|
||||||
|
<md:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
||||||
|
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://127.0.0.1:8010/auth/saml/logout" />
|
||||||
|
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
|
||||||
|
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://127.0.0.1:8010/auth/saml/acs" index="1" />
|
||||||
|
</md:SPSSODescriptor>
|
||||||
|
<md:Organization>
|
||||||
|
<md:OrganizationName xml:lang="en">Kimai</md:OrganizationName>
|
||||||
|
<md:OrganizationDisplayName xml:lang="en">Kimai</md:OrganizationDisplayName>
|
||||||
|
<md:OrganizationURL xml:lang="en">https://www.kimai.org</md:OrganizationURL>
|
||||||
|
</md:Organization>
|
||||||
|
<md:ContactPerson contactType="technical">
|
||||||
|
<md:GivenName>Kimai Admin</md:GivenName>
|
||||||
|
<md:EmailAddress>kimai-tech@example.com</md:EmailAddress>
|
||||||
|
</md:ContactPerson>
|
||||||
|
<md:ContactPerson contactType="support">
|
||||||
|
<md:GivenName>Kimai Support</md:GivenName>
|
||||||
|
<md:EmailAddress>kimai-support@example.com</md:EmailAddress>
|
||||||
|
</md:ContactPerson>
|
||||||
|
</md:EntityDescriptor>
|
||||||
|
EOD;
|
||||||
|
|
||||||
|
$oauth = $this->getAuth();
|
||||||
|
$sut = new SamlController($oauth);
|
||||||
|
$result = $sut->metadataAction();
|
||||||
|
|
||||||
|
self::assertInstanceOf(Response::class, $result);
|
||||||
|
self::assertEquals('xml', $result->headers->get('Content-Type'));
|
||||||
|
|
||||||
|
$expected = Xml::load($expected);
|
||||||
|
$actual = Xml::load($result->getContent());
|
||||||
|
|
||||||
|
// the "validUntil" attribute in the outer node changes per request
|
||||||
|
self::assertEquals($expected->firstChild->firstChild, $actual->firstChild->firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testLoginActionThrowsErrorOnSecurityErrorAttribute()
|
||||||
|
{
|
||||||
|
$this->expectException(\RuntimeException::class);
|
||||||
|
$this->expectExceptionMessage('My test error');
|
||||||
|
|
||||||
|
$request = new Request();
|
||||||
|
$request->setSession($this->createMock(SessionInterface::class));
|
||||||
|
$request->attributes->set(Security::AUTHENTICATION_ERROR, new \Exception('My test error'));
|
||||||
|
|
||||||
|
$oauth = $this->getAuth();
|
||||||
|
$sut = new SamlController($oauth);
|
||||||
|
$sut->loginAction($request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ use Hslavich\OneloginSamlBundle\Security\Authentication\Token\SamlToken;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
|
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
||||||
|
use Symfony\Component\Security\Core\Exception\AuthenticationException;
|
||||||
use Symfony\Component\Security\Core\User\ChainUserProvider;
|
use Symfony\Component\Security\Core\User\ChainUserProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,7 +27,7 @@ use Symfony\Component\Security\Core\User\ChainUserProvider;
|
||||||
*/
|
*/
|
||||||
class SamlProviderTest extends TestCase
|
class SamlProviderTest extends TestCase
|
||||||
{
|
{
|
||||||
protected function getSamlProvider($mapping = null, $loadUser = false): SamlProvider
|
protected function getSamlProvider($mapping = null, $loadUser = false, ?SamlUserFactory $userFactory = null): SamlProvider
|
||||||
{
|
{
|
||||||
if (null === $mapping) {
|
if (null === $mapping) {
|
||||||
$mapping = [
|
$mapping = [
|
||||||
|
@ -41,12 +42,16 @@ class SamlProviderTest extends TestCase
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (null === $userFactory) {
|
||||||
|
$userFactory = new SamlUserFactory($mapping);
|
||||||
|
}
|
||||||
|
|
||||||
$repository = $this->getMockBuilder(UserRepository::class)->disableOriginalConstructor()->getMock();
|
$repository = $this->getMockBuilder(UserRepository::class)->disableOriginalConstructor()->getMock();
|
||||||
if ($loadUser !== false) {
|
if ($loadUser !== false) {
|
||||||
$repository->expects($this->once())->method('loadUserByUsername')->willReturn($loadUser);
|
$repository->expects($this->once())->method('loadUserByUsername')->willReturn($loadUser);
|
||||||
}
|
}
|
||||||
$userProvider = new ChainUserProvider([new DoctrineUserProvider($repository)]);
|
$userProvider = new ChainUserProvider([new DoctrineUserProvider($repository)]);
|
||||||
$provider = new SamlProvider($repository, $userProvider, new SamlTokenFactory(), new SamlUserFactory($mapping));
|
$provider = new SamlProvider($repository, $userProvider, new SamlTokenFactory(), $userFactory);
|
||||||
|
|
||||||
return $provider;
|
return $provider;
|
||||||
}
|
}
|
||||||
|
@ -108,4 +113,22 @@ class SamlProviderTest extends TestCase
|
||||||
self::assertEquals('Tralalala', $tokenUser->getTitle());
|
self::assertEquals('Tralalala', $tokenUser->getTitle());
|
||||||
self::assertEquals('foo@example.com', $tokenUser->getEmail());
|
self::assertEquals('foo@example.com', $tokenUser->getEmail());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testAuthenticateThrowsAuthenticationException()
|
||||||
|
{
|
||||||
|
$this->expectException(AuthenticationException::class);
|
||||||
|
$this->expectExceptionMessage('Failed creating or hydrating user "foo1@example.com": Missing user attribute: Email');
|
||||||
|
|
||||||
|
$user = new User();
|
||||||
|
$user->setAuth(User::AUTH_SAML);
|
||||||
|
|
||||||
|
$token = new SamlToken([]);
|
||||||
|
$token->setUser('foo1@example.com');
|
||||||
|
$token->setAttributes([
|
||||||
|
'Chicken' => ['foo@example.com'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$sut = $this->getSamlProvider(null, $user);
|
||||||
|
$sut->authenticate($token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
33
tests/Saml/SamlAuthTest.php
Normal file
33
tests/Saml/SamlAuthTest.php
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Kimai time-tracking app.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Tests\Saml;
|
||||||
|
|
||||||
|
use App\Tests\Mocks\Saml\SamlAuthFactory;
|
||||||
|
use OneLogin\Saml2\Utils;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \App\Saml\SamlAuth
|
||||||
|
*/
|
||||||
|
class SamlAuthTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testCreateToken()
|
||||||
|
{
|
||||||
|
$previous = Utils::getProxyVars();
|
||||||
|
self::assertFalse($previous);
|
||||||
|
|
||||||
|
$sut = (new SamlAuthFactory($this))->create(null, true);
|
||||||
|
|
||||||
|
$current = Utils::getProxyVars();
|
||||||
|
self::assertTrue($current);
|
||||||
|
|
||||||
|
Utils::setProxyVars($previous);
|
||||||
|
}
|
||||||
|
}
|
37
tests/Utils/MenuItemModelTest.php
Normal file
37
tests/Utils/MenuItemModelTest.php
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Kimai time-tracking app.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Tests\Utils;
|
||||||
|
|
||||||
|
use App\Utils\MenuItemModel;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers \App\Utils\MenuItemModel
|
||||||
|
*/
|
||||||
|
class MenuItemModelTest extends TestCase
|
||||||
|
{
|
||||||
|
public function testChildRoutes()
|
||||||
|
{
|
||||||
|
$sut = new MenuItemModel('test', 'foo', 'bar');
|
||||||
|
|
||||||
|
self::assertFalse($sut->isChildRoute('blub'));
|
||||||
|
self::assertFalse($sut->isChildRoute('bla'));
|
||||||
|
|
||||||
|
$sut->addChildRoute('blub');
|
||||||
|
|
||||||
|
self::assertTrue($sut->isChildRoute('blub'));
|
||||||
|
self::assertFalse($sut->isChildRoute('bla'));
|
||||||
|
|
||||||
|
$sut->setChildRoutes(['bla']);
|
||||||
|
|
||||||
|
self::assertFalse($sut->isChildRoute('blub'));
|
||||||
|
self::assertTrue($sut->isChildRoute('bla'));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue