diff options
Diffstat (limited to 'tests/Unit')
29 files changed, 971 insertions, 156 deletions
diff --git a/tests/Unit/Controllers/AuthControllerTest.php b/tests/Unit/Controllers/AuthControllerTest.php index c5349cda..c3d9659c 100644 --- a/tests/Unit/Controllers/AuthControllerTest.php +++ b/tests/Unit/Controllers/AuthControllerTest.php @@ -3,40 +3,166 @@ namespace Engelsystem\Test\Unit\Controllers; use Engelsystem\Controllers\AuthController; +use Engelsystem\Helpers\Authenticator; +use Engelsystem\Http\Exceptions\ValidationException; +use Engelsystem\Http\Request; use Engelsystem\Http\Response; use Engelsystem\Http\UrlGeneratorInterface; +use Engelsystem\Http\Validation\Validator; +use Engelsystem\Models\User\Settings; +use Engelsystem\Models\User\User; +use Engelsystem\Test\Unit\HasDatabase; +use Illuminate\Support\Collection; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; +use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpFoundation\Session\SessionInterface; +use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; class AuthControllerTest extends TestCase { + use HasDatabase; + /** * @covers \Engelsystem\Controllers\AuthController::__construct - * @covers \Engelsystem\Controllers\AuthController::logout + * @covers \Engelsystem\Controllers\AuthController::login + * @covers \Engelsystem\Controllers\AuthController::showLogin */ - public function testLogout() + public function testLogin() { /** @var Response|MockObject $response */ $response = $this->createMock(Response::class); /** @var SessionInterface|MockObject $session */ - $session = $this->getMockForAbstractClass(SessionInterface::class); /** @var UrlGeneratorInterface|MockObject $url */ - $url = $this->getMockForAbstractClass(UrlGeneratorInterface::class); + /** @var Authenticator|MockObject $auth */ + list(, $session, $url, $auth) = $this->getMocks(); $session->expects($this->once()) - ->method('invalidate'); + ->method('get') + ->with('errors', []) + ->willReturn(['foo' => 'bar']); + $response->expects($this->once()) + ->method('withView') + ->with('pages/login') + ->willReturn($response); + + $controller = new AuthController($response, $session, $url, $auth); + $controller->login(); + } + + /** + * @covers \Engelsystem\Controllers\AuthController::postLogin + */ + public function testPostLogin() + { + $this->initDatabase(); + $request = new Request(); + /** @var Response|MockObject $response */ + $response = $this->createMock(Response::class); + /** @var UrlGeneratorInterface|MockObject $url */ + /** @var Authenticator|MockObject $auth */ + list(, , $url, $auth) = $this->getMocks(); + $session = new Session(new MockArraySessionStorage()); + /** @var Validator|MockObject $validator */ + $validator = new Validator(); + + $user = new User([ + 'name' => 'foo', + 'password' => '', + 'email' => '', + 'api_key' => '', + 'last_login_at' => null, + ]); + $user->forceFill(['id' => 42]); + $user->save(); + + $settings = new Settings(['language' => 'de_DE', 'theme' => '']); + $settings->user() + ->associate($user) + ->save(); + + $auth->expects($this->exactly(2)) + ->method('authenticate') + ->with('foo', 'bar') + ->willReturnOnConsecutiveCalls(null, $user); + + $response->expects($this->once()) + ->method('withView') + ->with('pages/login', ['errors' => Collection::make(['auth.not-found']), 'show_password_recovery' => true]) + ->willReturn($response); $response->expects($this->once()) ->method('redirectTo') - ->with('https://foo.bar/'); + ->with('news') + ->willReturn($response); + + // No credentials + $controller = new AuthController($response, $session, $url, $auth); + $controller->setValidator($validator); + try { + $controller->postLogin($request); + $this->fail('Login without credentials possible'); + } catch (ValidationException $e) { + } + + // Missing password + $request = new Request([], ['login' => 'foo']); + try { + $controller->postLogin($request); + $this->fail('Login without password possible'); + } catch (ValidationException $e) { + } + + // No user found + $request = new Request([], ['login' => 'foo', 'password' => 'bar']); + $controller->postLogin($request); + $this->assertEquals([], $session->all()); + + // Authenticated user + $controller->postLogin($request); + + $this->assertNotNull($user->last_login_at); + $this->assertEquals(['user_id' => 42, 'locale' => 'de_DE'], $session->all()); + } + + /** + * @covers \Engelsystem\Controllers\AuthController::logout + */ + public function testLogout() + { + /** @var Response $response */ + /** @var SessionInterface|MockObject $session */ + /** @var UrlGeneratorInterface|MockObject $url */ + /** @var Authenticator|MockObject $auth */ + list($response, $session, $url, $auth) = $this->getMocks(); + + $session->expects($this->once()) + ->method('invalidate'); $url->expects($this->once()) ->method('to') ->with('/') ->willReturn('https://foo.bar/'); - $controller = new AuthController($response, $session, $url); - $controller->logout(); + $controller = new AuthController($response, $session, $url, $auth); + $return = $controller->logout(); + + $this->assertEquals(['https://foo.bar/'], $return->getHeader('location')); + } + + /** + * @return array + */ + protected function getMocks() + { + $response = new Response(); + /** @var SessionInterface|MockObject $session */ + $session = $this->getMockForAbstractClass(SessionInterface::class); + /** @var UrlGeneratorInterface|MockObject $url */ + $url = $this->getMockForAbstractClass(UrlGeneratorInterface::class); + /** @var Authenticator|MockObject $auth */ + $auth = $this->createMock(Authenticator::class); + + return [$response, $session, $url, $auth]; } } diff --git a/tests/Unit/Controllers/BaseControllerTest.php b/tests/Unit/Controllers/BaseControllerTest.php index 738b538f..2adc9dc7 100644 --- a/tests/Unit/Controllers/BaseControllerTest.php +++ b/tests/Unit/Controllers/BaseControllerTest.php @@ -21,5 +21,7 @@ class BaseControllerTest extends TestCase 'dolor', ], ], $controller->getPermissions()); + + $this->assertTrue(method_exists($controller, 'setValidator')); } } diff --git a/tests/Unit/Controllers/Metrics/MetricsEngineTest.php b/tests/Unit/Controllers/Metrics/MetricsEngineTest.php index 38817b36..87a7dc88 100644 --- a/tests/Unit/Controllers/Metrics/MetricsEngineTest.php +++ b/tests/Unit/Controllers/Metrics/MetricsEngineTest.php @@ -66,4 +66,15 @@ class MetricsEngineTest extends TestCase $this->assertFalse($engine->canRender('/metrics.foo')); $this->assertTrue($engine->canRender('/metrics')); } + + /** + * @covers \Engelsystem\Controllers\Metrics\MetricsEngine::share + */ + public function testShare() + { + $engine = new MetricsEngine(); + + $engine->share('foo', 42); + $this->assertEquals('', $engine->get('/metrics')); + } } diff --git a/tests/Unit/Controllers/Stub/ControllerImplementation.php b/tests/Unit/Controllers/Stub/ControllerImplementation.php index 01d9f250..a8bf538c 100644 --- a/tests/Unit/Controllers/Stub/ControllerImplementation.php +++ b/tests/Unit/Controllers/Stub/ControllerImplementation.php @@ -14,12 +14,4 @@ class ControllerImplementation extends BaseController 'dolor', ], ]; - - /** - * @param array $permissions - */ - public function setPermissions(array $permissions) - { - $this->permissions = $permissions; - } } diff --git a/tests/Unit/Helpers/AuthenticatorServiceProviderTest.php b/tests/Unit/Helpers/AuthenticatorServiceProviderTest.php index b1767ebc..ab9b23ec 100644 --- a/tests/Unit/Helpers/AuthenticatorServiceProviderTest.php +++ b/tests/Unit/Helpers/AuthenticatorServiceProviderTest.php @@ -3,6 +3,7 @@ namespace Engelsystem\Test\Unit\Helpers; use Engelsystem\Application; +use Engelsystem\Config\Config; use Engelsystem\Helpers\Authenticator; use Engelsystem\Helpers\AuthenticatorServiceProvider; use Engelsystem\Http\Request; @@ -19,11 +20,19 @@ class AuthenticatorServiceProviderTest extends ServiceProviderTest $app = new Application(); $app->bind(ServerRequestInterface::class, Request::class); + $config = new Config(); + $config->set('password_algorithm', PASSWORD_DEFAULT); + $app->instance('config', $config); + $serviceProvider = new AuthenticatorServiceProvider($app); $serviceProvider->register(); $this->assertInstanceOf(Authenticator::class, $app->get(Authenticator::class)); $this->assertInstanceOf(Authenticator::class, $app->get('authenticator')); $this->assertInstanceOf(Authenticator::class, $app->get('auth')); + + /** @var Authenticator $auth */ + $auth = $app->get(Authenticator::class); + $this->assertEquals(PASSWORD_DEFAULT, $auth->getPasswordAlgorithm()); } } diff --git a/tests/Unit/Helpers/AuthenticatorTest.php b/tests/Unit/Helpers/AuthenticatorTest.php index 400278f2..83dc72ad 100644 --- a/tests/Unit/Helpers/AuthenticatorTest.php +++ b/tests/Unit/Helpers/AuthenticatorTest.php @@ -4,6 +4,7 @@ namespace Engelsystem\Test\Unit\Helpers; use Engelsystem\Helpers\Authenticator; use Engelsystem\Models\User\User; +use Engelsystem\Test\Unit\HasDatabase; use Engelsystem\Test\Unit\Helpers\Stub\UserModelImplementation; use Engelsystem\Test\Unit\ServiceProviderTest; use PHPUnit\Framework\MockObject\MockObject; @@ -12,6 +13,8 @@ use Symfony\Component\HttpFoundation\Session\Session; class AuthenticatorTest extends ServiceProviderTest { + use HasDatabase; + /** * @covers \Engelsystem\Helpers\Authenticator::__construct( * @covers \Engelsystem\Helpers\Authenticator::user @@ -29,7 +32,7 @@ class AuthenticatorTest extends ServiceProviderTest $session->expects($this->exactly(3)) ->method('get') - ->with('uid') + ->with('user_id') ->willReturnOnConsecutiveCalls( null, 42, @@ -114,16 +117,13 @@ class AuthenticatorTest extends ServiceProviderTest /** @var User|MockObject $user */ $user = $this->createMock(User::class); - $user->expects($this->once()) - ->method('save'); - - $session->expects($this->exactly(2)) + $session->expects($this->once()) ->method('get') - ->with('uid') + ->with('user_id') ->willReturn(42); $session->expects($this->once()) ->method('remove') - ->with('uid'); + ->with('user_id'); /** @var Authenticator|MockObject $auth */ $auth = $this->getMockBuilder(Authenticator::class) @@ -151,4 +151,115 @@ class AuthenticatorTest extends ServiceProviderTest // Permissions cached $this->assertTrue($auth->can('bar')); } + + /** + * @covers \Engelsystem\Helpers\Authenticator::authenticate + */ + public function testAuthenticate() + { + $this->initDatabase(); + + /** @var ServerRequestInterface|MockObject $request */ + $request = $this->getMockForAbstractClass(ServerRequestInterface::class); + /** @var Session|MockObject $session */ + $session = $this->createMock(Session::class); + $userRepository = new User(); + + (new User([ + 'name' => 'lorem', + 'password' => password_hash('testing', PASSWORD_DEFAULT), + 'email' => 'lorem@foo.bar', + 'api_key' => '', + ]))->save(); + (new User([ + 'name' => 'ipsum', + 'password' => '', + 'email' => 'ipsum@foo.bar', + 'api_key' => '', + ]))->save(); + + $auth = new Authenticator($request, $session, $userRepository); + $this->assertNull($auth->authenticate('not-existing', 'foo')); + $this->assertNull($auth->authenticate('ipsum', 'wrong-password')); + $this->assertInstanceOf(User::class, $auth->authenticate('lorem', 'testing')); + $this->assertInstanceOf(User::class, $auth->authenticate('lorem@foo.bar', 'testing')); + } + + /** + * @covers \Engelsystem\Helpers\Authenticator::verifyPassword + */ + public function testVerifyPassword() + { + $this->initDatabase(); + $password = password_hash('testing', PASSWORD_ARGON2I); + $user = new User([ + 'name' => 'lorem', + 'password' => $password, + 'email' => 'lorem@foo.bar', + 'api_key' => '', + ]); + $user->save(); + + /** @var Authenticator|MockObject $auth */ + $auth = $this->getMockBuilder(Authenticator::class) + ->disableOriginalConstructor() + ->setMethods(['setPassword']) + ->getMock(); + + $auth->expects($this->once()) + ->method('setPassword') + ->with($user, 'testing'); + $auth->setPasswordAlgorithm(PASSWORD_BCRYPT); + + $this->assertFalse($auth->verifyPassword($user, 'randomStuff')); + $this->assertTrue($auth->verifyPassword($user, 'testing')); + } + + /** + * @covers \Engelsystem\Helpers\Authenticator::setPassword + */ + public function testSetPassword() + { + $this->initDatabase(); + $user = new User([ + 'name' => 'ipsum', + 'password' => '', + 'email' => 'ipsum@foo.bar', + 'api_key' => '', + ]); + $user->save(); + + $auth = $this->getAuthenticator(); + $auth->setPasswordAlgorithm(PASSWORD_ARGON2I); + + $auth->setPassword($user, 'FooBar'); + $this->assertTrue($user->isClean()); + + $this->assertTrue(password_verify('FooBar', $user->password)); + $this->assertFalse(password_needs_rehash($user->password, PASSWORD_ARGON2I)); + } + + /** + * @covers \Engelsystem\Helpers\Authenticator::setPasswordAlgorithm + * @covers \Engelsystem\Helpers\Authenticator::getPasswordAlgorithm + */ + public function testPasswordAlgorithm() + { + $auth = $this->getAuthenticator(); + + $auth->setPasswordAlgorithm(PASSWORD_ARGON2I); + $this->assertEquals(PASSWORD_ARGON2I, $auth->getPasswordAlgorithm()); + } + + /** + * @return Authenticator + */ + protected function getAuthenticator() + { + return new class extends Authenticator + { + /** @noinspection PhpMissingParentConstructorInspection */ + public function __construct() { } + }; + } } diff --git a/tests/Unit/Helpers/Translation/Assets/fo_OO/default.mo b/tests/Unit/Helpers/Translation/Assets/fo_OO/default.mo Binary files differnew file mode 100644 index 00000000..96f1f3ca --- /dev/null +++ b/tests/Unit/Helpers/Translation/Assets/fo_OO/default.mo diff --git a/tests/Unit/Helpers/Translation/Assets/fo_OO/default.po b/tests/Unit/Helpers/Translation/Assets/fo_OO/default.po new file mode 100644 index 00000000..015bc36d --- /dev/null +++ b/tests/Unit/Helpers/Translation/Assets/fo_OO/default.po @@ -0,0 +1,3 @@ +# Testing content +msgid "foo.bar" +msgstr "Foo Bar!" diff --git a/tests/Unit/Helpers/Translation/GettextTranslatorTest.php b/tests/Unit/Helpers/Translation/GettextTranslatorTest.php new file mode 100644 index 00000000..825cf5b7 --- /dev/null +++ b/tests/Unit/Helpers/Translation/GettextTranslatorTest.php @@ -0,0 +1,67 @@ +<?php + +namespace Engelsystem\Test\Unit\Helpers\Translation; + +use Engelsystem\Helpers\Translation\GettextTranslator; +use Engelsystem\Helpers\Translation\TranslationNotFound; +use Engelsystem\Test\Unit\ServiceProviderTest; +use Gettext\Translation; +use Gettext\Translations; + +class GettextTranslatorTest extends ServiceProviderTest +{ + /** + * @covers \Engelsystem\Helpers\Translation\GettextTranslator::assertHasTranslation() + */ + public function testNoTranslation() + { + $translations = $this->getTranslations(); + + $translator = new GettextTranslator(); + $translator->loadTranslations($translations); + + $this->assertEquals('Translation!', $translator->gettext('test.value')); + + $this->expectException(TranslationNotFound::class); + $this->expectExceptionMessage('//foo.bar'); + + $translator->gettext('foo.bar'); + } + + /** + * @covers \Engelsystem\Helpers\Translation\GettextTranslator::dpgettext() + */ + public function testDpgettext() + { + $translations = $this->getTranslations(); + + $translator = new GettextTranslator(); + $translator->loadTranslations($translations); + + $this->assertEquals('Translation!', $translator->dpgettext(null, null, 'test.value')); + } + + /** + * @covers \Engelsystem\Helpers\Translation\GettextTranslator::dnpgettext() + */ + public function testDnpgettext() + { + $translations = $this->getTranslations(); + + $translator = new GettextTranslator(); + $translator->loadTranslations($translations); + + $this->assertEquals('Translations!', $translator->dnpgettext(null, null, 'test.value', 'test.values', 2)); + } + + protected function getTranslations(): Translations + { + $translations = new Translations(); + $translations[] = + (new Translation(null, 'test.value', 'test.values')) + ->setTranslation('Translation!') + ->setPluralTranslations(['Translations!']); + + return $translations; + } +} diff --git a/tests/Unit/Helpers/TranslationServiceProviderTest.php b/tests/Unit/Helpers/Translation/TranslationServiceProviderTest.php index 41c08aa5..91307bdd 100644 --- a/tests/Unit/Helpers/TranslationServiceProviderTest.php +++ b/tests/Unit/Helpers/Translation/TranslationServiceProviderTest.php @@ -1,10 +1,10 @@ <?php -namespace Engelsystem\Test\Unit\Helpers; +namespace Engelsystem\Test\Unit\Helpers\Translation; use Engelsystem\Config\Config; -use Engelsystem\Helpers\TranslationServiceProvider; -use Engelsystem\Helpers\Translator; +use Engelsystem\Helpers\Translation\TranslationServiceProvider; +use Engelsystem\Helpers\Translation\Translator; use Engelsystem\Test\Unit\ServiceProviderTest; use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\HttpFoundation\Session\Session; @@ -12,13 +12,16 @@ use Symfony\Component\HttpFoundation\Session\Session; class TranslationServiceProviderTest extends ServiceProviderTest { /** - * @covers \Engelsystem\Helpers\TranslationServiceProvider::register() + * @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::register() */ - public function testRegister() + public function testRegister(): void { + $defaultLocale = 'fo_OO'; + $locale = 'te_ST.WTF-9'; + $locales = ['fo_OO' => 'Foo', 'fo_OO.BAR' => 'Foo (Bar)', 'te_ST.WTF-9' => 'WTF\'s Testing?']; + $config = new Config(['locales' => $locales, 'default_locale' => $defaultLocale]); + $app = $this->getApp(['make', 'instance', 'get']); - /** @var Config|MockObject $config */ - $config = $this->createMock(Config::class); /** @var Session|MockObject $session */ $session = $this->createMock(Session::class); /** @var Translator|MockObject $translator */ @@ -27,31 +30,14 @@ class TranslationServiceProviderTest extends ServiceProviderTest /** @var TranslationServiceProvider|MockObject $serviceProvider */ $serviceProvider = $this->getMockBuilder(TranslationServiceProvider::class) ->setConstructorArgs([$app]) - ->setMethods(['initGettext', 'setLocale']) + ->setMethods(['setLocale']) ->getMock(); - $serviceProvider->expects($this->once()) - ->method('initGettext'); - $app->expects($this->exactly(2)) ->method('get') ->withConsecutive(['config'], ['session']) ->willReturnOnConsecutiveCalls($config, $session); - $defaultLocale = 'fo_OO'; - $locale = 'te_ST.WTF-9'; - $locales = ['fo_OO' => 'Foo', 'fo_OO.BAR' => 'Foo (Bar)', 'te_ST.WTF-9' => 'WTF\'s Testing?']; - $config->expects($this->exactly(2)) - ->method('get') - ->withConsecutive( - ['locales'], - ['default_locale'] - ) - ->willReturnOnConsecutiveCalls( - $locales, - $defaultLocale - ); - $session->expects($this->once()) ->method('get') ->with('locale', $defaultLocale) @@ -65,9 +51,11 @@ class TranslationServiceProviderTest extends ServiceProviderTest ->with( Translator::class, [ - 'locale' => $locale, - 'locales' => $locales, - 'localeChangeCallback' => [$serviceProvider, 'setLocale'], + 'locale' => $locale, + 'locales' => $locales, + 'fallbackLocale' => 'en_US', + 'getTranslatorCallback' => [$serviceProvider, 'getTranslator'], + 'localeChangeCallback' => [$serviceProvider, 'setLocale'], ] ) ->willReturn($translator); @@ -81,4 +69,22 @@ class TranslationServiceProviderTest extends ServiceProviderTest $serviceProvider->register(); } + + /** + * @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::getTranslator() + */ + public function testGetTranslator(): void + { + $app = $this->getApp(['get']); + $serviceProvider = new TranslationServiceProvider($app); + + $this->setExpects($app, 'get', ['path.lang'], __DIR__ . '/Assets'); + + // Get translator + $translator = $serviceProvider->getTranslator('fo_OO'); + $this->assertEquals('Foo Bar!', $translator->gettext('foo.bar')); + + // Retry from cache + $serviceProvider->getTranslator('fo_OO'); + } } diff --git a/tests/Unit/Helpers/Translation/TranslatorTest.php b/tests/Unit/Helpers/Translation/TranslatorTest.php new file mode 100644 index 00000000..c173209a --- /dev/null +++ b/tests/Unit/Helpers/Translation/TranslatorTest.php @@ -0,0 +1,134 @@ +<?php + +namespace Engelsystem\Test\Unit\Helpers\Translation; + +use Engelsystem\Helpers\Translation\GettextTranslator; +use Engelsystem\Helpers\Translation\TranslationNotFound; +use Engelsystem\Helpers\Translation\Translator; +use Engelsystem\Test\Unit\ServiceProviderTest; +use PHPUnit\Framework\MockObject\MockObject; +use stdClass; + +class TranslatorTest extends ServiceProviderTest +{ + /** + * @covers \Engelsystem\Helpers\Translation\Translator::__construct + * @covers \Engelsystem\Helpers\Translation\Translator::getLocale + * @covers \Engelsystem\Helpers\Translation\Translator::getLocales + * @covers \Engelsystem\Helpers\Translation\Translator::hasLocale + * @covers \Engelsystem\Helpers\Translation\Translator::setLocale + * @covers \Engelsystem\Helpers\Translation\Translator::setLocales + */ + public function testInit() + { + $locales = ['te_ST' => 'Tests', 'fo_OO' => 'SomeFOO']; + $locale = 'te_ST'; + + /** @var callable|MockObject $localeChange */ + $localeChange = $this->getMockBuilder(stdClass::class) + ->setMethods(['__invoke']) + ->getMock(); + $localeChange->expects($this->exactly(2)) + ->method('__invoke') + ->withConsecutive(['te_ST'], ['fo_OO']); + + $translator = new Translator($locale, 'fo_OO', function () { }, $locales, $localeChange); + + $this->assertEquals($locales, $translator->getLocales()); + $this->assertEquals($locale, $translator->getLocale()); + + $translator->setLocale('fo_OO'); + $this->assertEquals('fo_OO', $translator->getLocale()); + + $newLocales = ['lo_RM' => 'Lorem', 'ip_SU-M' => 'Ipsum']; + $translator->setLocales($newLocales); + $this->assertEquals($newLocales, $translator->getLocales()); + + $this->assertTrue($translator->hasLocale('ip_SU-M')); + $this->assertFalse($translator->hasLocale('te_ST')); + } + + /** + * @covers \Engelsystem\Helpers\Translation\Translator::translate + */ + public function testTranslate() + { + /** @var Translator|MockObject $translator */ + $translator = $this->getMockBuilder(Translator::class) + ->setConstructorArgs(['de_DE', 'en_US', function () { }, ['de_DE' => 'Deutsch']]) + ->setMethods(['translateText']) + ->getMock(); + $translator->expects($this->exactly(2)) + ->method('translateText') + ->withConsecutive(['gettext', ['Hello!'], []], ['gettext', ['My favourite number is %u!'], [3]]) + ->willReturnOnConsecutiveCalls('Hallo!', 'Meine Lieblingszahl ist die 3!'); + + $return = $translator->translate('Hello!'); + $this->assertEquals('Hallo!', $return); + + $return = $translator->translate('My favourite number is %u!', [3]); + $this->assertEquals('Meine Lieblingszahl ist die 3!', $return); + } + + /** + * @covers \Engelsystem\Helpers\Translation\Translator::translatePlural + */ + public function testTranslatePlural() + { + /** @var Translator|MockObject $translator */ + $translator = $this->getMockBuilder(Translator::class) + ->setConstructorArgs(['de_DE', 'en_US', function () { }, ['de_DE' => 'Deutsch']]) + ->setMethods(['translateText']) + ->getMock(); + $translator->expects($this->once()) + ->method('translateText') + ->with('ngettext', ['%s apple', '%s apples', 2], [2]) + ->willReturn('2 Äpfel'); + + $return = $translator->translatePlural('%s apple', '%s apples', 2, [2]); + $this->assertEquals('2 Äpfel', $return); + } + + /** + * @covers \Engelsystem\Helpers\Translation\Translator::translatePlural + * @covers \Engelsystem\Helpers\Translation\Translator::translateText + * @covers \Engelsystem\Helpers\Translation\Translator::replaceText + */ + public function testReplaceText() + { + /** @var GettextTranslator|MockObject $gtt */ + $gtt = $this->createMock(GettextTranslator::class); + /** @var callable|MockObject $getTranslator */ + $getTranslator = $this->getMockBuilder(stdClass::class) + ->setMethods(['__invoke']) + ->getMock(); + $getTranslator->expects($this->exactly(5)) + ->method('__invoke') + ->withConsecutive(['te_ST'], ['fo_OO'], ['te_ST'], ['fo_OO'], ['te_ST']) + ->willReturn($gtt); + + $i = 0; + $gtt->expects($this->exactly(4)) + ->method('gettext') + ->willReturnCallback(function () use (&$i) { + $i++; + if ($i != 4) { + throw new TranslationNotFound(); + } + + return 'Lorem %s???'; + }); + $this->setExpects($gtt, 'ngettext', ['foo.barf'], 'Lorem %s!'); + + $translator = new Translator('te_ST', 'fo_OO', $getTranslator, ['te_ST' => 'Test', 'fo_OO' => 'Foo']); + + // No translation + $this->assertEquals('foo.bar', $translator->translate('foo.bar')); + + // Fallback translation + $this->assertEquals('Lorem test2???', $translator->translate('foo.batz', ['test2'])); + + // Successful translation + $this->assertEquals('Lorem test3!', $translator->translatePlural('foo.barf', 'foo.bar2', 3, ['test3'])); + } +} diff --git a/tests/Unit/Helpers/TranslatorTest.php b/tests/Unit/Helpers/TranslatorTest.php deleted file mode 100644 index 45ca769b..00000000 --- a/tests/Unit/Helpers/TranslatorTest.php +++ /dev/null @@ -1,90 +0,0 @@ -<?php - -namespace Engelsystem\Test\Unit\Helpers; - -use Engelsystem\Helpers\Translator; -use Engelsystem\Test\Unit\ServiceProviderTest; -use PHPUnit\Framework\MockObject\MockObject; -use stdClass; - -class TranslatorTest extends ServiceProviderTest -{ - /** - * @covers \Engelsystem\Helpers\Translator::__construct - * @covers \Engelsystem\Helpers\Translator::getLocale - * @covers \Engelsystem\Helpers\Translator::getLocales - * @covers \Engelsystem\Helpers\Translator::hasLocale - * @covers \Engelsystem\Helpers\Translator::setLocale - * @covers \Engelsystem\Helpers\Translator::setLocales - */ - public function testInit() - { - $locales = ['te_ST.ER-01' => 'Tests', 'fo_OO' => 'SomeFOO']; - $locale = 'te_ST.ER-01'; - - /** @var callable|MockObject $callable */ - $callable = $this->getMockBuilder(stdClass::class) - ->setMethods(['__invoke']) - ->getMock(); - $callable->expects($this->exactly(2)) - ->method('__invoke') - ->withConsecutive(['te_ST.ER-01'], ['fo_OO']); - - $translator = new Translator($locale, $locales, $callable); - - $this->assertEquals($locales, $translator->getLocales()); - $this->assertEquals($locale, $translator->getLocale()); - - $translator->setLocale('fo_OO'); - $this->assertEquals('fo_OO', $translator->getLocale()); - - $newLocales = ['lo_RM' => 'Lorem', 'ip_SU-M' => 'Ipsum']; - $translator->setLocales($newLocales); - $this->assertEquals($newLocales, $translator->getLocales()); - - $this->assertTrue($translator->hasLocale('ip_SU-M')); - $this->assertFalse($translator->hasLocale('te_ST.ER-01')); - } - - /** - * @covers \Engelsystem\Helpers\Translator::replaceText - * @covers \Engelsystem\Helpers\Translator::translate - */ - public function testTranslate() - { - /** @var Translator|MockObject $translator */ - $translator = $this->getMockBuilder(Translator::class) - ->setConstructorArgs(['de_DE.UTF-8', ['de_DE.UTF-8' => 'Deutsch']]) - ->setMethods(['translateGettext']) - ->getMock(); - $translator->expects($this->exactly(2)) - ->method('translateGettext') - ->withConsecutive(['Hello!'], ['My favourite number is %u!']) - ->willReturnOnConsecutiveCalls('Hallo!', 'Meine Lieblingszahl ist die %u!'); - - $return = $translator->translate('Hello!'); - $this->assertEquals('Hallo!', $return); - - $return = $translator->translate('My favourite number is %u!', [3]); - $this->assertEquals('Meine Lieblingszahl ist die 3!', $return); - } - - /** - * @covers \Engelsystem\Helpers\Translator::translatePlural - */ - public function testTranslatePlural() - { - /** @var Translator|MockObject $translator */ - $translator = $this->getMockBuilder(Translator::class) - ->setConstructorArgs(['de_DE.UTF-8', ['de_DE.UTF-8' => 'Deutsch']]) - ->setMethods(['translateGettextPlural']) - ->getMock(); - $translator->expects($this->once()) - ->method('translateGettextPlural') - ->with('%s apple', '%s apples', 2) - ->willReturn('2 Äpfel'); - - $return = $translator->translatePlural('%s apple', '%s apples', 2, [2]); - $this->assertEquals('2 Äpfel', $return); - } -} diff --git a/tests/Unit/HelpersTest.php b/tests/Unit/HelpersTest.php index ad677cb3..09362a90 100644 --- a/tests/Unit/HelpersTest.php +++ b/tests/Unit/HelpersTest.php @@ -6,7 +6,7 @@ use Engelsystem\Application; use Engelsystem\Config\Config; use Engelsystem\Container\Container; use Engelsystem\Helpers\Authenticator; -use Engelsystem\Helpers\Translator; +use Engelsystem\Helpers\Translation\Translator; use Engelsystem\Http\Request; use Engelsystem\Http\Response; use Engelsystem\Http\UrlGeneratorInterface; diff --git a/tests/Unit/Http/Exceptions/ValidationExceptionTest.php b/tests/Unit/Http/Exceptions/ValidationExceptionTest.php new file mode 100644 index 00000000..c5a38b5a --- /dev/null +++ b/tests/Unit/Http/Exceptions/ValidationExceptionTest.php @@ -0,0 +1,25 @@ +<?php + +namespace Engelsystem\Test\Unit\Http\Exceptions; + +use Engelsystem\Http\Exceptions\ValidationException; +use Engelsystem\Http\Validation\Validator; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +class ValidationExceptionTest extends TestCase +{ + /** + * @covers \Engelsystem\Http\Exceptions\ValidationException::__construct + * @covers \Engelsystem\Http\Exceptions\ValidationException::getValidator + */ + public function testConstruct() + { + /** @var Validator|MockObject $validator */ + $validator = $this->createMock(Validator::class); + + $exception = new ValidationException($validator); + + $this->assertEquals($validator, $exception->getValidator()); + } +} diff --git a/tests/Unit/Http/UrlGeneratorServiceProviderTest.php b/tests/Unit/Http/UrlGeneratorServiceProviderTest.php index 61bf3e7c..6d18f160 100644 --- a/tests/Unit/Http/UrlGeneratorServiceProviderTest.php +++ b/tests/Unit/Http/UrlGeneratorServiceProviderTest.php @@ -19,7 +19,7 @@ class UrlGeneratorServiceProviderTest extends ServiceProviderTest $urlGenerator = $this->getMockBuilder(UrlGenerator::class) ->getMock(); - $app = $this->getApp(); + $app = $this->getApp(['make', 'instance', 'bind']); $this->setExpects($app, 'make', [UrlGenerator::class], $urlGenerator); $app->expects($this->exactly(2)) @@ -29,6 +29,9 @@ class UrlGeneratorServiceProviderTest extends ServiceProviderTest ['http.urlGenerator', $urlGenerator], [UrlGeneratorInterface::class, $urlGenerator] ); + $app->expects($this->once()) + ->method('bind') + ->with(UrlGeneratorInterface::class, UrlGenerator::class); $serviceProvider = new UrlGeneratorServiceProvider($app); $serviceProvider->register(); diff --git a/tests/Unit/Http/Validation/Rules/InTest.php b/tests/Unit/Http/Validation/Rules/InTest.php new file mode 100644 index 00000000..e5688d90 --- /dev/null +++ b/tests/Unit/Http/Validation/Rules/InTest.php @@ -0,0 +1,19 @@ +<?php + +namespace Engelsystem\Test\Unit\Http\Validation\Rules; + +use Engelsystem\Http\Validation\Rules\In; +use Engelsystem\Test\Unit\TestCase; + +class InTest extends TestCase +{ + /** + * @covers \Engelsystem\Http\Validation\Rules\In::__construct + */ + public function testConstruct() + { + $rule = new In('foo,bar'); + + $this->assertEquals(['foo', 'bar'], $rule->haystack); + } +} diff --git a/tests/Unit/Http/Validation/Rules/NotInTest.php b/tests/Unit/Http/Validation/Rules/NotInTest.php new file mode 100644 index 00000000..9be12336 --- /dev/null +++ b/tests/Unit/Http/Validation/Rules/NotInTest.php @@ -0,0 +1,20 @@ +<?php + +namespace Engelsystem\Test\Unit\Http\Validation\Rules; + +use Engelsystem\Http\Validation\Rules\NotIn; +use Engelsystem\Test\Unit\TestCase; + +class NotInTest extends TestCase +{ + /** + * @covers \Engelsystem\Http\Validation\Rules\NotIn::validate + */ + public function testConstruct() + { + $rule = new NotIn('foo,bar'); + + $this->assertTrue($rule->validate('lorem')); + $this->assertFalse($rule->validate('foo')); + } +} diff --git a/tests/Unit/Http/Validation/Stub/ValidatesRequestImplementation.php b/tests/Unit/Http/Validation/Stub/ValidatesRequestImplementation.php new file mode 100644 index 00000000..772b1dc9 --- /dev/null +++ b/tests/Unit/Http/Validation/Stub/ValidatesRequestImplementation.php @@ -0,0 +1,27 @@ +<?php + +namespace Engelsystem\Test\Unit\Http\Validation\Stub; + +use Engelsystem\Controllers\BaseController; +use Engelsystem\Http\Request; + +class ValidatesRequestImplementation extends BaseController +{ + /** + * @param Request $request + * @param array $rules + * @return array + */ + public function validateData(Request $request, array $rules) + { + return $this->validate($request, $rules); + } + + /** + * @return bool + */ + public function hasValidator() + { + return !is_null($this->validator); + } +} diff --git a/tests/Unit/Http/Validation/ValidatesRequestTest.php b/tests/Unit/Http/Validation/ValidatesRequestTest.php new file mode 100644 index 00000000..8011bd03 --- /dev/null +++ b/tests/Unit/Http/Validation/ValidatesRequestTest.php @@ -0,0 +1,46 @@ +<?php + +namespace Engelsystem\Test\Unit\Http\Validation; + +use Engelsystem\Http\Exceptions\ValidationException; +use Engelsystem\Http\Request; +use Engelsystem\Http\Validation\Validator; +use Engelsystem\Test\Unit\Http\Validation\Stub\ValidatesRequestImplementation; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; + +class ValidatesRequestTest extends TestCase +{ + /** + * @covers \Engelsystem\Http\Validation\ValidatesRequest::validate + * @covers \Engelsystem\Http\Validation\ValidatesRequest::setValidator + */ + public function testValidate() + { + /** @var Validator|MockObject $validator */ + $validator = $this->createMock(Validator::class); + $validator->expects($this->exactly(2)) + ->method('validate') + ->withConsecutive( + [['foo' => 'bar'], ['foo' => 'required']], + [[], ['foo' => 'required']] + ) + ->willReturnOnConsecutiveCalls( + true, + false + ); + $validator->expects($this->once()) + ->method('getData') + ->willReturn(['foo' => 'bar']); + + $implementation = new ValidatesRequestImplementation(); + $implementation->setValidator($validator); + + $return = $implementation->validateData(new Request([], ['foo' => 'bar']), ['foo' => 'required']); + + $this->assertEquals(['foo' => 'bar'], $return); + + $this->expectException(ValidationException::class); + $implementation->validateData(new Request([], []), ['foo' => 'required']); + } +} diff --git a/tests/Unit/Http/Validation/ValidationServiceProviderTest.php b/tests/Unit/Http/Validation/ValidationServiceProviderTest.php new file mode 100644 index 00000000..969f4351 --- /dev/null +++ b/tests/Unit/Http/Validation/ValidationServiceProviderTest.php @@ -0,0 +1,34 @@ +<?php + +namespace Engelsystem\Test\Unit\Http\Validation; + +use Engelsystem\Application; +use Engelsystem\Http\Validation\ValidationServiceProvider; +use Engelsystem\Http\Validation\Validator; +use Engelsystem\Test\Unit\Http\Validation\Stub\ValidatesRequestImplementation; +use Engelsystem\Test\Unit\ServiceProviderTest; +use stdClass; + +class ValidationServiceProviderTest extends ServiceProviderTest +{ + /** + * @covers \Engelsystem\Http\Validation\ValidationServiceProvider::register + */ + public function testRegister() + { + $app = new Application(); + + $serviceProvider = new ValidationServiceProvider($app); + $serviceProvider->register(); + + $this->assertTrue($app->has(Validator::class)); + $this->assertTrue($app->has('validator')); + + /** @var ValidatesRequestImplementation $validatesRequest */ + $validatesRequest = $app->make(ValidatesRequestImplementation::class); + $this->assertTrue($validatesRequest->hasValidator()); + + // Test afterResolving early return + $app->make(stdClass::class); + } +} diff --git a/tests/Unit/Http/Validation/ValidatorTest.php b/tests/Unit/Http/Validation/ValidatorTest.php new file mode 100644 index 00000000..450e5d4e --- /dev/null +++ b/tests/Unit/Http/Validation/ValidatorTest.php @@ -0,0 +1,142 @@ +<?php + +namespace Engelsystem\Test\Unit\Http\Validation; + +use Engelsystem\Http\Validation\Validator; +use InvalidArgumentException; +use PHPUnit\Framework\TestCase; + +class ValidatorTest extends TestCase +{ + /** + * @covers \Engelsystem\Http\Validation\Validator::validate + * @covers \Engelsystem\Http\Validation\Validator::getData + * @covers \Engelsystem\Http\Validation\Validator::getErrors + */ + public function testValidate() + { + $val = new Validator(); + + $this->assertTrue($val->validate( + ['foo' => 'bar', 'lorem' => 'on', 'dolor' => 'bla'], + ['lorem' => 'accepted'] + )); + $this->assertEquals(['lorem' => 'on'], $val->getData()); + + $this->assertFalse($val->validate( + [], + ['lorem' => 'required|min:3'] + )); + $this->assertEquals( + ['lorem' => ['validation.lorem.required', 'validation.lorem.min']], + $val->getErrors() + ); + } + + /** + * @covers \Engelsystem\Http\Validation\Validator::validate + */ + public function testValidateChaining() + { + $val = new Validator(); + + $this->assertTrue($val->validate( + ['lorem' => 10], + ['lorem' => 'required|min:3|max:10'] + )); + $this->assertTrue($val->validate( + ['lorem' => 3], + ['lorem' => 'required|min:3|max:10'] + )); + + $this->assertFalse($val->validate( + ['lorem' => 2], + ['lorem' => 'required|min:3|max:10'] + )); + $this->assertFalse($val->validate( + ['lorem' => 42], + ['lorem' => 'required|min:3|max:10'] + )); + } + + /** + * @covers \Engelsystem\Http\Validation\Validator::validate + */ + public function testValidateNotImplemented() + { + $val = new Validator(); + + $this->expectException(InvalidArgumentException::class); + + $val->validate( + ['lorem' => 'bar'], + ['foo' => 'never_implemented'] + ); + } + + /** + * @covers \Engelsystem\Http\Validation\Validator::map + * @covers \Engelsystem\Http\Validation\Validator::mapBack + */ + public function testValidateMapping() + { + $val = new Validator(); + + $this->assertTrue($val->validate( + ['foo' => 'bar'], + ['foo' => 'required'] + )); + $this->assertTrue($val->validate( + ['foo' => '0'], + ['foo' => 'int'] + )); + $this->assertTrue($val->validate( + ['foo' => 'on'], + ['foo' => 'accepted'] + )); + + $this->assertFalse($val->validate( + [], + ['lorem' => 'required'] + )); + $this->assertEquals( + ['lorem' => ['validation.lorem.required']], + $val->getErrors() + ); + } + + /** + * @covers \Engelsystem\Http\Validation\Validator::validate + */ + public function testValidateNesting() + { + $val = new Validator(); + + $this->assertTrue($val->validate( + [], + ['foo' => 'not|required'] + )); + + $this->assertTrue($val->validate( + ['foo' => 'foo'], + ['foo' => 'not|int'] + )); + $this->assertFalse($val->validate( + ['foo' => 1], + ['foo' => 'not|int'] + )); + + $this->assertTrue($val->validate( + [], + ['foo' => 'optional|int'] + )); + $this->assertTrue($val->validate( + ['foo' => '33'], + ['foo' => 'optional|int'] + )); + $this->assertFalse($val->validate( + ['foo' => 'T'], + ['foo' => 'optional|int'] + )); + } +} diff --git a/tests/Unit/Middleware/ErrorHandlerTest.php b/tests/Unit/Middleware/ErrorHandlerTest.php index 6c37b651..a9fdd71a 100644 --- a/tests/Unit/Middleware/ErrorHandlerTest.php +++ b/tests/Unit/Middleware/ErrorHandlerTest.php @@ -2,14 +2,23 @@ namespace Engelsystem\Test\Unit\Middleware; +use Engelsystem\Application; use Engelsystem\Http\Exceptions\HttpException; +use Engelsystem\Http\Exceptions\ValidationException; +use Engelsystem\Http\Psr7ServiceProvider; +use Engelsystem\Http\Request; use Engelsystem\Http\Response; +use Engelsystem\Http\ResponseServiceProvider; +use Engelsystem\Http\Validation\Validator; use Engelsystem\Middleware\ErrorHandler; use Engelsystem\Test\Unit\Middleware\Stub\ReturnResponseMiddlewareHandler; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Server\RequestHandlerInterface; +use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; use Twig_LoaderInterface as TwigLoader; class ErrorHandlerTest extends TestCase @@ -104,7 +113,7 @@ class ErrorHandlerTest extends TestCase /** * @covers \Engelsystem\Middleware\ErrorHandler::process */ - public function testProcessException() + public function testProcessHttpException() { /** @var ServerRequestInterface|MockObject $request */ $request = $this->createMock(ServerRequestInterface::class); @@ -146,6 +155,67 @@ class ErrorHandlerTest extends TestCase /** * @covers \Engelsystem\Middleware\ErrorHandler::process + * @covers \Engelsystem\Middleware\ErrorHandler::getPreviousUrl + */ + public function testProcessValidationException() + { + /** @var TwigLoader|MockObject $twigLoader */ + $twigLoader = $this->createMock(TwigLoader::class); + $handler = $this->getMockForAbstractClass(RequestHandlerInterface::class); + $validator = $this->createMock(Validator::class); + + $handler->expects($this->exactly(2)) + ->method('handle') + ->willReturnCallback(function () use ($validator) { + throw new ValidationException($validator); + }); + + $validator->expects($this->exactly(2)) + ->method('getErrors') + ->willReturn(['foo' => ['validation.foo.numeric']]); + + $session = new Session(new MockArraySessionStorage()); + $session->set('errors', ['validation' => ['foo' => ['validation.foo.required']]]); + $request = Request::create( + '/foo/bar', + 'POST', + ['foo' => 'bar', 'password' => 'Test123', 'password_confirmation' => 'Test1234'] + ); + $request->setSession($session); + + /** @var Application $app */ + $app = app(); + (new ResponseServiceProvider($app))->register(); + (new Psr7ServiceProvider($app))->register(); + + $errorHandler = new ErrorHandler($twigLoader); + + $return = $errorHandler->process($request, $handler); + + $this->assertEquals(302, $return->getStatusCode()); + $this->assertEquals('/', $return->getHeaderLine('location')); + $this->assertEquals([ + 'errors' => [ + 'validation' => [ + 'foo' => [ + 'validation.foo.required', + 'validation.foo.numeric', + ], + ], + ], + 'form-data' => [ + 'foo' => 'bar', + ], + ], $session->all()); + + $request = $request->withAddedHeader('referer', '/foo/batz'); + $return = $errorHandler->process($request, $handler); + + $this->assertEquals('/foo/batz', $return->getHeaderLine('location')); + } + + /** + * @covers \Engelsystem\Middleware\ErrorHandler::process */ public function testProcessContentTypeSniffer() { @@ -153,7 +223,7 @@ class ErrorHandlerTest extends TestCase $request = $this->createMock(ServerRequestInterface::class); /** @var TwigLoader|MockObject $twigLoader */ $twigLoader = $this->createMock(TwigLoader::class); - $response = new Response('<!DOCTYPE html><html><body><h1>Hi!</h1></body></html>', 500); + $response = new Response('<!DOCTYPE html><html lang="en"><body><h1>Hi!</h1></body></html>', 500); $returnResponseHandler = new ReturnResponseMiddlewareHandler($response); /** @var ErrorHandler|MockObject $errorHandler */ diff --git a/tests/Unit/Middleware/LegacyMiddlewareTest.php b/tests/Unit/Middleware/LegacyMiddlewareTest.php index f14a38ed..cce7371a 100644 --- a/tests/Unit/Middleware/LegacyMiddlewareTest.php +++ b/tests/Unit/Middleware/LegacyMiddlewareTest.php @@ -3,7 +3,7 @@ namespace Engelsystem\Test\Unit\Middleware; use Engelsystem\Helpers\Authenticator; -use Engelsystem\Helpers\Translator; +use Engelsystem\Helpers\Translation\Translator; use Engelsystem\Http\Request; use Engelsystem\Middleware\LegacyMiddleware; use PHPUnit\Framework\MockObject\MockObject; diff --git a/tests/Unit/Middleware/SetLocaleTest.php b/tests/Unit/Middleware/SetLocaleTest.php index dc68d83a..a586f6b7 100644 --- a/tests/Unit/Middleware/SetLocaleTest.php +++ b/tests/Unit/Middleware/SetLocaleTest.php @@ -2,7 +2,7 @@ namespace Engelsystem\Test\Unit\Middleware; -use Engelsystem\Helpers\Translator; +use Engelsystem\Helpers\Translation\Translator; use Engelsystem\Middleware\SetLocale; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; diff --git a/tests/Unit/Renderer/EngineTest.php b/tests/Unit/Renderer/EngineTest.php new file mode 100644 index 00000000..659d85c5 --- /dev/null +++ b/tests/Unit/Renderer/EngineTest.php @@ -0,0 +1,25 @@ +<?php + +namespace Engelsystem\Test\Unit\Renderer; + +use Engelsystem\Test\Unit\Renderer\Stub\EngineImplementation; +use PHPUnit\Framework\TestCase; + +class EngineTest extends TestCase +{ + /** + * @covers \Engelsystem\Renderer\Engine::share + */ + public function testShare() + { + $engine = new EngineImplementation(); + $engine->share(['foo' => ['bar' => 'baz', 'lorem' => 'ipsum']]); + $engine->share(['foo' => ['lorem' => 'dolor']]); + $engine->share('key', 'value'); + + $this->assertEquals( + ['foo' => ['bar' => 'baz', 'lorem' => 'dolor'], 'key' => 'value'], + $engine->getSharedData() + ); + } +} diff --git a/tests/Unit/Renderer/HtmlEngineTest.php b/tests/Unit/Renderer/HtmlEngineTest.php index 4a31e4bc..f76e7528 100644 --- a/tests/Unit/Renderer/HtmlEngineTest.php +++ b/tests/Unit/Renderer/HtmlEngineTest.php @@ -16,11 +16,12 @@ class HtmlEngineTest extends TestCase public function testGet() { $engine = new HtmlEngine(); + $engine->share('shared_data', 'tester'); - $file = $this->createTempFile('<div>%main_content%</div>'); + $file = $this->createTempFile('<div>%main_content% is a %shared_data%</div>'); $data = $engine->get($file, ['main_content' => 'Lorem ipsum dolor sit']); - $this->assertEquals('<div>Lorem ipsum dolor sit</div>', $data); + $this->assertEquals('<div>Lorem ipsum dolor sit is a tester</div>', $data); } /** diff --git a/tests/Unit/Renderer/Stub/EngineImplementation.php b/tests/Unit/Renderer/Stub/EngineImplementation.php new file mode 100644 index 00000000..fc436569 --- /dev/null +++ b/tests/Unit/Renderer/Stub/EngineImplementation.php @@ -0,0 +1,32 @@ +<?php + +namespace Engelsystem\Test\Unit\Renderer\Stub; + +use Engelsystem\Renderer\Engine; + +class EngineImplementation extends Engine +{ + /** + * @inheritdoc + */ + public function get(string $path, array $data = []): string + { + return ''; + } + + /** + * @inheritdoc + */ + public function canRender(string $path): bool + { + return true; + } + + /** + * @return array + */ + public function getSharedData(): array + { + return $this->sharedData; + } +} diff --git a/tests/Unit/Renderer/Twig/Extensions/TranslationTest.php b/tests/Unit/Renderer/Twig/Extensions/TranslationTest.php index 18705683..0b055c44 100644 --- a/tests/Unit/Renderer/Twig/Extensions/TranslationTest.php +++ b/tests/Unit/Renderer/Twig/Extensions/TranslationTest.php @@ -2,7 +2,7 @@ namespace Engelsystem\Test\Unit\Renderer\Twig\Extensions; -use Engelsystem\Helpers\Translator; +use Engelsystem\Helpers\Translation\Translator; use Engelsystem\Renderer\Twig\Extensions\Translation; use PHPUnit\Framework\MockObject\MockObject; use Twig_Extensions_TokenParser_Trans as TranslationTokenParser; diff --git a/tests/Unit/Renderer/TwigEngineTest.php b/tests/Unit/Renderer/TwigEngineTest.php index 9d0618f1..5e5e59d9 100644 --- a/tests/Unit/Renderer/TwigEngineTest.php +++ b/tests/Unit/Renderer/TwigEngineTest.php @@ -20,16 +20,16 @@ class TwigEngineTest extends TestCase $twig = $this->createMock(Twig::class); $path = 'foo.twig'; - $data = ['lorem' => 'ipsum']; - $twig->expects($this->once()) ->method('render') - ->with($path, $data) - ->willReturn('LoremIpsum!'); + ->with($path, ['lorem' => 'ipsum', 'shared' => 'data']) + ->willReturn('LoremIpsum data!'); $engine = new TwigEngine($twig); - $return = $engine->get($path, $data); - $this->assertEquals('LoremIpsum!', $return); + $engine->share('shared', 'data'); + + $return = $engine->get($path, ['lorem' => 'ipsum']); + $this->assertEquals('LoremIpsum data!', $return); } |