diff options
Diffstat (limited to 'tests/Unit/Helpers')
-rw-r--r-- | tests/Unit/Helpers/AuthenticatorServiceProviderTest.php | 9 | ||||
-rw-r--r-- | tests/Unit/Helpers/AuthenticatorTest.php | 125 | ||||
-rw-r--r-- | tests/Unit/Helpers/Translation/Assets/fo_OO/default.mo | bin | 0 -> 73 bytes | |||
-rw-r--r-- | tests/Unit/Helpers/Translation/Assets/fo_OO/default.po | 3 | ||||
-rw-r--r-- | tests/Unit/Helpers/Translation/GettextTranslatorTest.php | 67 | ||||
-rw-r--r-- | tests/Unit/Helpers/Translation/TranslationServiceProviderTest.php (renamed from tests/Unit/Helpers/TranslationServiceProviderTest.php) | 62 | ||||
-rw-r--r-- | tests/Unit/Helpers/Translation/TranslatorTest.php | 134 | ||||
-rw-r--r-- | tests/Unit/Helpers/TranslatorTest.php | 90 |
8 files changed, 365 insertions, 125 deletions
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); - } -} |