diff options
Diffstat (limited to 'tests')
28 files changed, 610 insertions, 98 deletions
diff --git a/tests/Feature/Database/DatabaseServiceProviderTest.php b/tests/Feature/Database/DatabaseServiceProviderTest.php index d66ed25c..aa4dbc7b 100644 --- a/tests/Feature/Database/DatabaseServiceProviderTest.php +++ b/tests/Feature/Database/DatabaseServiceProviderTest.php @@ -2,10 +2,9 @@ namespace Engelsystem\Test\Feature\Database; -use Engelsystem\Application; use Engelsystem\Config\Config; +use Engelsystem\Database\Database; use Engelsystem\Database\DatabaseServiceProvider; -use PHPUnit\Framework\MockObject\MockObject; class DatabaseServiceProviderTest extends DatabaseTest { @@ -14,27 +13,13 @@ class DatabaseServiceProviderTest extends DatabaseTest */ public function testRegister() { - /** @var Config|MockObject $config */ - $config = $this->getMockBuilder(Config::class) - ->getMock(); + $this->app->instance('config', new Config([ + 'database' => $this->getDbConfig(), + 'timezone' => 'UTC', + ])); - /** @var Application|MockObject $app */ - $app = $this->getMockBuilder(Application::class) - ->setMethods(['get']) - ->getMock(); - Application::setInstance($app); - - $app->expects($this->once()) - ->method('get') - ->with('config') - ->willReturn($config); - - $config->expects($this->atLeastOnce()) - ->method('get') - ->with('database') - ->willReturn($this->getDbConfig()); - - $serviceProvider = new DatabaseServiceProvider($app); + $serviceProvider = new DatabaseServiceProvider($this->app); $serviceProvider->register(); + $this->assertTrue($this->app->has(Database::class)); } } diff --git a/tests/Feature/Database/DatabaseTest.php b/tests/Feature/Database/DatabaseTest.php index 11df6779..0116e526 100644 --- a/tests/Feature/Database/DatabaseTest.php +++ b/tests/Feature/Database/DatabaseTest.php @@ -2,7 +2,7 @@ namespace Engelsystem\Test\Feature\Database; -use PHPUnit\Framework\TestCase; +use Engelsystem\Test\Unit\TestCase; abstract class DatabaseTest extends TestCase { diff --git a/tests/Unit/Controllers/AuthControllerTest.php b/tests/Unit/Controllers/AuthControllerTest.php index 6c237264..a12ed6d6 100644 --- a/tests/Unit/Controllers/AuthControllerTest.php +++ b/tests/Unit/Controllers/AuthControllerTest.php @@ -12,9 +12,8 @@ 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 Engelsystem\Test\Unit\TestCase; 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; @@ -66,6 +65,7 @@ class AuthControllerTest extends TestCase $session = new Session(new MockArraySessionStorage()); /** @var Validator|MockObject $validator */ $validator = new Validator(); + $session->set('errors', [['bar' => 'some.bar.error']]); $user = new User([ 'name' => 'foo', @@ -89,7 +89,7 @@ class AuthControllerTest extends TestCase $response->expects($this->once()) ->method('withView') - ->with('pages/login', ['errors' => Collection::make(['auth.not-found'])]) + ->with('pages/login', ['errors' => collect(['some.bar.error', 'auth.not-found'])]) ->willReturn($response); $response->expects($this->once()) ->method('redirectTo') diff --git a/tests/Unit/Controllers/Metrics/StatsTest.php b/tests/Unit/Controllers/Metrics/StatsTest.php index fa78d8c3..9204f7db 100644 --- a/tests/Unit/Controllers/Metrics/StatsTest.php +++ b/tests/Unit/Controllers/Metrics/StatsTest.php @@ -155,8 +155,8 @@ class StatsTest extends TestCase $this->initDatabase(); $this->addUsers(); - (new PasswordReset(['use_id' => 1, 'token' => 'loremIpsum123']))->save(); - (new PasswordReset(['use_id' => 3, 'token' => '5omeR4nd0mTok3N']))->save(); + (new PasswordReset(['user_id' => 1, 'token' => 'loremIpsum123']))->save(); + (new PasswordReset(['user_id' => 3, 'token' => '5omeR4nd0mTok3N']))->save(); $stats = new Stats($this->database); $this->assertEquals(2, $stats->passwordResets()); diff --git a/tests/Unit/Controllers/PasswordResetControllerTest.php b/tests/Unit/Controllers/PasswordResetControllerTest.php new file mode 100644 index 00000000..54046cef --- /dev/null +++ b/tests/Unit/Controllers/PasswordResetControllerTest.php @@ -0,0 +1,266 @@ +<?php + +namespace Engelsystem\Test\Unit\Controllers; + +use Engelsystem\Config\Config; +use Engelsystem\Controllers\PasswordResetController; +use Engelsystem\Helpers\Authenticator; +use Engelsystem\Http\Exceptions\HttpNotFound; +use Engelsystem\Http\Exceptions\ValidationException; +use Engelsystem\Http\Request; +use Engelsystem\Http\Response; +use Engelsystem\Http\Validation\Validator; +use Engelsystem\Mail\EngelsystemMailer; +use Engelsystem\Models\User\PasswordReset; +use Engelsystem\Models\User\User; +use Engelsystem\Renderer\Renderer; +use Engelsystem\Test\Unit\HasDatabase; +use Engelsystem\Test\Unit\TestCase; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\Test\TestLogger; +use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage; + +class PasswordResetControllerTest extends TestCase +{ + use HasDatabase; + + /** @var array */ + protected $args = []; + + /** + * @covers \Engelsystem\Controllers\PasswordResetController::reset + * @covers \Engelsystem\Controllers\PasswordResetController::__construct + */ + public function testReset(): void + { + $controller = $this->getController('pages/password/reset'); + $response = $controller->reset(); + + $this->assertEquals(200, $response->getStatusCode()); + } + + /** + * @covers \Engelsystem\Controllers\PasswordResetController::postReset + */ + public function testPostReset(): void + { + $this->initDatabase(); + $request = new Request([], ['email' => 'foo@bar.batz']); + $user = $this->createUser(); + + $controller = $this->getController( + 'pages/password/reset-success', + ['type' => 'email', 'errors' => collect()] + ); + /** @var TestLogger $log */ + $log = $this->args['log']; + /** @var EngelsystemMailer|MockObject $mailer */ + $mailer = $this->args['mailer']; + $this->setExpects($mailer, 'sendViewTranslated'); + + $controller->postReset($request); + + $this->assertNotEmpty(PasswordReset::find($user->id)->first()); + $this->assertTrue($log->hasInfoThatContains($user->name)); + } + + /** + * @covers \Engelsystem\Controllers\PasswordResetController::postReset + */ + public function testPostResetInvalidRequest(): void + { + $request = new Request(); + + $controller = $this->getController(); + + $this->expectException(ValidationException::class); + $controller->postReset($request); + } + + /** + * @covers \Engelsystem\Controllers\PasswordResetController::postReset + */ + public function testPostResetNoUser(): void + { + $this->initDatabase(); + $request = new Request([], ['email' => 'foo@bar.batz']); + + $controller = $this->getController( + 'pages/password/reset-success', + ['type' => 'email', 'errors' => collect()] + ); + + $controller->postReset($request); + } + + /** + * @covers \Engelsystem\Controllers\PasswordResetController::resetPassword + * @covers \Engelsystem\Controllers\PasswordResetController::requireToken + */ + public function testResetPassword(): void + { + $this->initDatabase(); + + $user = $this->createUser(); + $token = $this->createToken($user); + $request = new Request([], [], ['token' => $token->token]); + + $controller = $this->getController('pages/password/reset-form'); + + $controller->resetPassword($request); + } + + /** + * @covers \Engelsystem\Controllers\PasswordResetController::resetPassword + * @covers \Engelsystem\Controllers\PasswordResetController::requireToken + */ + public function testResetPasswordNoToken(): void + { + $this->initDatabase(); + $controller = $this->getController(); + + $this->expectException(HttpNotFound::class); + $controller->resetPassword(new Request()); + } + + /** + * @covers \Engelsystem\Controllers\PasswordResetController::postResetPassword + */ + public function testPostResetPassword(): void + { + $this->initDatabase(); + + $this->app->instance('config', new Config(['min_password_length' => 3])); + $user = $this->createUser(); + $token = $this->createToken($user); + $password = 'SomeRandomPasswordForAmazingSecurity'; + $request = new Request( + [], + ['password' => $password, 'password_confirmation' => $password], + ['token' => $token->token] + ); + + $controller = $this->getController( + 'pages/password/reset-success', + ['type' => 'reset', 'errors' => collect()] + ); + + $auth = new Authenticator($request, $this->args['session'], $user); + $this->app->instance('authenticator', $auth); + + $response = $controller->postResetPassword($request); + $this->assertEquals(200, $response->getStatusCode()); + + $this->assertEmpty(PasswordReset::find($user->id)); + $this->assertNotNull(auth()->authenticate($user->name, $password)); + } + + /** + * @covers \Engelsystem\Controllers\PasswordResetController::postResetPassword + * @covers \Engelsystem\Controllers\PasswordResetController::showView + */ + public function testPostResetPasswordNotMatching(): void + { + $this->initDatabase(); + + $this->app->instance('config', new Config(['min_password_length' => 3])); + $user = $this->createUser(); + $token = $this->createToken($user); + $password = 'SomeRandomPasswordForAmazingSecurity'; + $request = new Request( + [], + ['password' => $password, 'password_confirmation' => $password . 'OrNot'], + ['token' => $token->token] + ); + + $controller = $this->getController( + 'pages/password/reset-form', + ['errors' => collect(['some.other.error', 'validation.password.confirmed'])] + ); + /** @var Session $session */ + $session = $this->args['session']; + $session->set('errors', ['foo' => ['bar' => 'some.other.error']]); + + $controller->postResetPassword($request); + $this->assertEmpty($session->get('errors')); + } + + /** + * @return array + */ + protected function getControllerArgs(): array + { + $response = new Response(); + $session = new Session(new MockArraySessionStorage()); + /** @var EngelsystemMailer|MockObject $mailer */ + $mailer = $this->createMock(EngelsystemMailer::class); + $log = new TestLogger(); + $renderer = $this->createMock(Renderer::class); + $response->setRenderer($renderer); + + return $this->args = [ + 'response' => $response, + 'session' => $session, + 'mailer' => $mailer, + 'log' => $log, + 'renderer' => $renderer + ]; + } + + /** + * @param string $view + * @param array $data + * @return PasswordResetController + */ + protected function getController(?string $view = null, ?array $data = null): PasswordResetController + { + /** @var Response $response */ + /** @var Session $session */ + /** @var EngelsystemMailer|MockObject $mailer */ + /** @var TestLogger $log */ + /** @var Renderer|MockObject $renderer */ + list($response, $session, $mailer, $log, $renderer) = array_values($this->getControllerArgs()); + $controller = new PasswordResetController($response, $session, $mailer, $log); + $controller->setValidator(new Validator()); + + if ($view) { + $args = [$view]; + if ($data) { + $args[] = $data; + } + + $this->setExpects($renderer, 'render', $args, 'Foo'); + } + + return $controller; + } + + /** + * @return User + */ + protected function createUser(): User + { + $user = new User([ + 'name' => 'foo', + 'password' => '', + 'email' => 'foo@bar.batz', + 'api_key' => '', + ]); + $user->save(); + + return $user; + } + + /** + * @param User $user + * @return PasswordReset + */ + protected function createToken(User $user): PasswordReset + { + $reset = new PasswordReset(['user_id' => $user->id, 'token' => 'SomeTestToken123']); + $reset->save(); + + return $reset; + } +} diff --git a/tests/Unit/Database/DatabaseServiceProviderTest.php b/tests/Unit/Database/DatabaseServiceProviderTest.php index c3e4c5d0..241c47b7 100644 --- a/tests/Unit/Database/DatabaseServiceProviderTest.php +++ b/tests/Unit/Database/DatabaseServiceProviderTest.php @@ -100,7 +100,10 @@ class DatabaseServiceProviderTest extends ServiceProviderTest $app = $this->getApp(['get', 'make', 'instance']); $this->setExpects($app, 'get', ['config'], $config); - $this->setExpects($config, 'get', ['database'], $dbConfigData, $this->atLeastOnce()); + $config->expects($this->exactly(2)) + ->method('get') + ->withConsecutive(['timezone'], ['database']) + ->willReturnOnConsecutiveCalls('UTC', $dbConfigData); $app->expects($this->atLeastOnce()) ->method('make') diff --git a/tests/Unit/HasDatabase.php b/tests/Unit/HasDatabase.php index 7a58bb2b..dbaa253e 100644 --- a/tests/Unit/HasDatabase.php +++ b/tests/Unit/HasDatabase.php @@ -2,7 +2,6 @@ namespace Engelsystem\Test\Unit; -use Engelsystem\Application; use Engelsystem\Database\Database; use Engelsystem\Database\Migration\Migrate; use Engelsystem\Database\Migration\MigrationServiceProvider; @@ -27,12 +26,11 @@ trait HasDatabase $connection->getPdo()->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->database = new Database($connection); - $app = new Application(); - $app->instance(Database::class, $this->database); - $app->register(MigrationServiceProvider::class); + $this->app->instance(Database::class, $this->database); + $this->app->register(MigrationServiceProvider::class); /** @var Migrate $migration */ - $migration = $app->get('db.migration'); + $migration = $this->app->get('db.migration'); $migration->initMigration(); $this->database diff --git a/tests/Unit/Helpers/Translation/Assets/ba_RR/default.po b/tests/Unit/Helpers/Translation/Assets/ba_RR/default.po new file mode 100644 index 00000000..887e2daa --- /dev/null +++ b/tests/Unit/Helpers/Translation/Assets/ba_RR/default.po @@ -0,0 +1,3 @@ +# Testing content +msgid "foo.bar" +msgstr "B Arr!" diff --git a/tests/Unit/Helpers/Translation/TranslationServiceProviderTest.php b/tests/Unit/Helpers/Translation/TranslationServiceProviderTest.php index 91307bdd..e55fdf02 100644 --- a/tests/Unit/Helpers/Translation/TranslationServiceProviderTest.php +++ b/tests/Unit/Helpers/Translation/TranslationServiceProviderTest.php @@ -12,7 +12,7 @@ use Symfony\Component\HttpFoundation\Session\Session; class TranslationServiceProviderTest extends ServiceProviderTest { /** - * @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::register() + * @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::register */ public function testRegister(): void { @@ -21,7 +21,7 @@ class TranslationServiceProviderTest extends ServiceProviderTest $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']); + $app = $this->getApp(['make', 'singleton', 'alias', 'get']); /** @var Session|MockObject $session */ $session = $this->createMock(Session::class); /** @var Translator|MockObject $translator */ @@ -30,7 +30,7 @@ class TranslationServiceProviderTest extends ServiceProviderTest /** @var TranslationServiceProvider|MockObject $serviceProvider */ $serviceProvider = $this->getMockBuilder(TranslationServiceProvider::class) ->setConstructorArgs([$app]) - ->setMethods(['setLocale']) + ->onlyMethods(['setLocale']) ->getMock(); $app->expects($this->exactly(2)) @@ -60,18 +60,22 @@ class TranslationServiceProviderTest extends ServiceProviderTest ) ->willReturn($translator); - $app->expects($this->exactly(2)) - ->method('instance') - ->withConsecutive( - [Translator::class, $translator], - ['translator', $translator] - ); + $app->expects($this->once()) + ->method('singleton') + ->willReturnCallback(function (string $abstract, callable $callback) use ($translator) { + $this->assertEquals(Translator::class, $abstract); + $this->assertEquals($translator, $callback()); + }); + + $app->expects($this->once()) + ->method('alias') + ->with(Translator::class, 'translator'); $serviceProvider->register(); } /** - * @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::getTranslator() + * @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::getTranslator */ public function testGetTranslator(): void { @@ -87,4 +91,20 @@ class TranslationServiceProviderTest extends ServiceProviderTest // Retry from cache $serviceProvider->getTranslator('fo_OO'); } + + /** + * @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::getTranslator + * @covers \Engelsystem\Helpers\Translation\TranslationServiceProvider::getFile + */ + public function testGetTranslatorFromPo(): void + { + $app = $this->getApp(['get']); + $this->setExpects($app, 'get', ['path.lang'], __DIR__ . '/Assets'); + + $serviceProvider = new TranslationServiceProvider($app); + + // Get translator using a .po file + $translator = $serviceProvider->getTranslator('ba_RR'); + $this->assertEquals('B Arr!', $translator->gettext('foo.bar')); + } } diff --git a/tests/Unit/Http/Exceptions/HttpNotFoundTest.php b/tests/Unit/Http/Exceptions/HttpNotFoundTest.php new file mode 100644 index 00000000..a39ea087 --- /dev/null +++ b/tests/Unit/Http/Exceptions/HttpNotFoundTest.php @@ -0,0 +1,22 @@ +<?php + +namespace Engelsystem\Test\Unit\Http\Exceptions; + +use Engelsystem\Http\Exceptions\HttpNotFound; +use PHPUnit\Framework\TestCase; + +class HttpNotFoundTest extends TestCase +{ + /** + * @covers \Engelsystem\Http\Exceptions\HttpNotFound::__construct + */ + public function testConstruct() + { + $exception = new HttpNotFound(); + $this->assertEquals(404, $exception->getStatusCode()); + $this->assertEquals('', $exception->getMessage()); + + $exception = new HttpNotFound('Nothing to see here!'); + $this->assertEquals('Nothing to see here!', $exception->getMessage()); + } +} diff --git a/tests/Unit/Http/ResponseTest.php b/tests/Unit/Http/ResponseTest.php index 34f76513..b8e6e527 100644 --- a/tests/Unit/Http/ResponseTest.php +++ b/tests/Unit/Http/ResponseTest.php @@ -55,6 +55,7 @@ class ResponseTest extends TestCase /** * @covers \Engelsystem\Http\Response::withView + * @covers \Engelsystem\Http\Response::setRenderer */ public function testWithView() { @@ -73,6 +74,17 @@ class ResponseTest extends TestCase $this->assertEquals('Foo ipsum!', $newResponse->getContent()); $this->assertEquals(505, $newResponse->getStatusCode()); $this->assertArraySubset(['test' => ['er']], $newResponse->getHeaders()); + + /** @var REnderer|MockObject $renderer */ + $anotherRenderer = $this->createMock(Renderer::class); + $anotherRenderer->expects($this->once()) + ->method('render') + ->with('bar') + ->willReturn('Stuff'); + + $response->setRenderer($anotherRenderer); + $response = $response->withView('bar'); + $this->assertEquals('Stuff', $response->getContent()); } /** diff --git a/tests/Unit/Http/SessionHandlers/DatabaseHandlerTest.php b/tests/Unit/Http/SessionHandlers/DatabaseHandlerTest.php index 14f23c00..0325ccfe 100644 --- a/tests/Unit/Http/SessionHandlers/DatabaseHandlerTest.php +++ b/tests/Unit/Http/SessionHandlers/DatabaseHandlerTest.php @@ -4,7 +4,7 @@ namespace Engelsystem\Test\Unit\Http\SessionHandlers; use Engelsystem\Http\SessionHandlers\DatabaseHandler; use Engelsystem\Test\Unit\HasDatabase; -use PHPUnit\Framework\TestCase; +use Engelsystem\Test\Unit\TestCase; class DatabaseHandlerTest extends TestCase { @@ -90,6 +90,7 @@ class DatabaseHandlerTest extends TestCase */ protected function setUp(): void { + parent::setUp(); $this->initDatabase(); } } diff --git a/tests/Unit/Http/Validation/Rules/BetweenTest.php b/tests/Unit/Http/Validation/Rules/BetweenTest.php new file mode 100644 index 00000000..130d2f93 --- /dev/null +++ b/tests/Unit/Http/Validation/Rules/BetweenTest.php @@ -0,0 +1,28 @@ +<?php + +namespace Engelsystem\Test\Unit\Http\Validation\Rules; + +use Engelsystem\Http\Validation\Rules\Between; +use Engelsystem\Test\Unit\TestCase; + +class BetweenTest extends TestCase +{ + /** + * @covers \Engelsystem\Http\Validation\Rules\Between + */ + public function testValidate() + { + $rule = new Between(3, 10); + $this->assertFalse($rule->validate(1)); + $this->assertFalse($rule->validate('11')); + $this->assertTrue($rule->validate(5)); + $this->assertFalse($rule->validate('AS')); + $this->assertFalse($rule->validate('TestContentThatCounts')); + $this->assertTrue($rule->validate('TESTING')); + + $rule = new Between('2042-01-01', '2042-10-10'); + $this->assertFalse($rule->validate('2000-01-01')); + $this->assertFalse($rule->validate('3000-01-01')); + $this->assertTrue($rule->validate('2042-05-11')); + } +} diff --git a/tests/Unit/Http/Validation/Rules/MaxTest.php b/tests/Unit/Http/Validation/Rules/MaxTest.php new file mode 100644 index 00000000..3f4d9516 --- /dev/null +++ b/tests/Unit/Http/Validation/Rules/MaxTest.php @@ -0,0 +1,26 @@ +<?php + +namespace Engelsystem\Test\Unit\Http\Validation\Rules; + +use Engelsystem\Http\Validation\Rules\Max; +use Engelsystem\Test\Unit\TestCase; + +class MaxTest extends TestCase +{ + /** + * @covers \Engelsystem\Http\Validation\Rules\Max + */ + public function testValidate() + { + $rule = new Max(3); + $this->assertFalse($rule->validate(10)); + $this->assertFalse($rule->validate('22')); + $this->assertTrue($rule->validate(3)); + $this->assertFalse($rule->validate('TEST')); + $this->assertTrue($rule->validate('AS')); + + $rule = new Max('2042-01-01'); + $this->assertFalse($rule->validate('2100-01-01')); + $this->assertTrue($rule->validate('2000-01-01')); + } +} diff --git a/tests/Unit/Http/Validation/Rules/MinTest.php b/tests/Unit/Http/Validation/Rules/MinTest.php new file mode 100644 index 00000000..56350802 --- /dev/null +++ b/tests/Unit/Http/Validation/Rules/MinTest.php @@ -0,0 +1,26 @@ +<?php + +namespace Engelsystem\Test\Unit\Http\Validation\Rules; + +use Engelsystem\Http\Validation\Rules\Min; +use Engelsystem\Test\Unit\TestCase; + +class MinTest extends TestCase +{ + /** + * @covers \Engelsystem\Http\Validation\Rules\Min + */ + public function testValidate() + { + $rule = new Min(3); + $this->assertFalse($rule->validate(1)); + $this->assertFalse($rule->validate('2')); + $this->assertTrue($rule->validate(3)); + $this->assertFalse($rule->validate('AS')); + $this->assertTrue($rule->validate('TEST')); + + $rule = new Min('2042-01-01'); + $this->assertFalse($rule->validate('2000-01-01')); + $this->assertTrue($rule->validate('2345-01-01')); + } +} diff --git a/tests/Unit/Http/Validation/Rules/StringInputLengthTest.php b/tests/Unit/Http/Validation/Rules/StringInputLengthTest.php new file mode 100644 index 00000000..5c4dc512 --- /dev/null +++ b/tests/Unit/Http/Validation/Rules/StringInputLengthTest.php @@ -0,0 +1,37 @@ +<?php + +namespace Engelsystem\Test\Unit\Http\Validation\Rules; + +use Engelsystem\Test\Unit\Http\Validation\Rules\Stub\UsesStringInputLength; +use Engelsystem\Test\Unit\TestCase; + +class StringInputLengthTest extends TestCase +{ + /** + * @covers \Engelsystem\Http\Validation\Rules\StringInputLength::validate + * @covers \Engelsystem\Http\Validation\Rules\StringInputLength::isDateTime + * @dataProvider validateProvider + * @param mixed $input + * @param mixed $expectedInput + */ + public function testValidate($input, $expectedInput) + { + $rule = new UsesStringInputLength(); + $rule->validate($input); + + $this->assertEquals($expectedInput, $rule->lastInput); + } + + /** + * @return array[] + */ + public function validateProvider() + { + return [ + ['TEST', 4], + ['?', 1], + ['2042-01-01 00:00', '2042-01-01 00:00'], + ['3', '3'], + ]; + } +} diff --git a/tests/Unit/Http/Validation/Rules/Stub/ParentClassImplementation.php b/tests/Unit/Http/Validation/Rules/Stub/ParentClassImplementation.php new file mode 100644 index 00000000..1b6aaaf5 --- /dev/null +++ b/tests/Unit/Http/Validation/Rules/Stub/ParentClassImplementation.php @@ -0,0 +1,23 @@ +<?php + +namespace Engelsystem\Test\Unit\Http\Validation\Rules\Stub; + +class ParentClassImplementation +{ + /** @var bool */ + public $validateResult = true; + + /** @var mixed */ + public $lastInput; + + /** + * @param mixed $input + * @return bool + */ + public function validate($input): bool + { + $this->lastInput = $input; + + return $this->validateResult; + } +} diff --git a/tests/Unit/Http/Validation/Rules/Stub/UsesStringInputLength.php b/tests/Unit/Http/Validation/Rules/Stub/UsesStringInputLength.php new file mode 100644 index 00000000..3522304c --- /dev/null +++ b/tests/Unit/Http/Validation/Rules/Stub/UsesStringInputLength.php @@ -0,0 +1,10 @@ +<?php + +namespace Engelsystem\Test\Unit\Http\Validation\Rules\Stub; + +use Engelsystem\Http\Validation\Rules\StringInputLength; + +class UsesStringInputLength extends ParentClassImplementation +{ + use StringInputLength; +} diff --git a/tests/Unit/Http/Validation/ValidatorTest.php b/tests/Unit/Http/Validation/ValidatorTest.php index 450e5d4e..124673df 100644 --- a/tests/Unit/Http/Validation/ValidatorTest.php +++ b/tests/Unit/Http/Validation/ValidatorTest.php @@ -50,9 +50,10 @@ class ValidatorTest extends TestCase )); $this->assertFalse($val->validate( - ['lorem' => 2], - ['lorem' => 'required|min:3|max:10'] + ['lorem' => 'OMG'], + ['lorem' => 'required|min:4|max:10'] )); + $this->assertEquals(['lorem' => ['validation.lorem.min']], $val->getErrors()); $this->assertFalse($val->validate( ['lorem' => 42], ['lorem' => 'required|min:3|max:10'] diff --git a/tests/Unit/Mail/EngelsystemMailerTest.php b/tests/Unit/Mail/EngelsystemMailerTest.php index 12dc3b0b..cdbdf435 100644 --- a/tests/Unit/Mail/EngelsystemMailerTest.php +++ b/tests/Unit/Mail/EngelsystemMailerTest.php @@ -2,15 +2,22 @@ namespace Engelsystem\Test\Unit\Mail; +use Engelsystem\Helpers\Translation\Translator; use Engelsystem\Mail\EngelsystemMailer; +use Engelsystem\Models\User\Contact; +use Engelsystem\Models\User\Settings; +use Engelsystem\Models\User\User; use Engelsystem\Renderer\Renderer; +use Engelsystem\Test\Unit\HasDatabase; +use Engelsystem\Test\Unit\TestCase; use PHPUnit\Framework\MockObject\MockObject; -use PHPUnit\Framework\TestCase; use Swift_Mailer as SwiftMailer; use Swift_Message as SwiftMessage; class EngelsystemMailerTest extends TestCase { + use HasDatabase; + /** * @covers \Engelsystem\Mail\EngelsystemMailer::__construct * @covers \Engelsystem\Mail\EngelsystemMailer::sendView @@ -24,22 +31,70 @@ class EngelsystemMailerTest extends TestCase /** @var EngelsystemMailer|MockObject $mailer */ $mailer = $this->getMockBuilder(EngelsystemMailer::class) ->setConstructorArgs(['mailer' => $swiftMailer, 'view' => $view]) - ->setMethods(['send']) + ->onlyMethods(['send']) ->getMock(); - $mailer->expects($this->once()) - ->method('send') - ->with('foo@bar.baz', 'Lorem dolor', 'Rendered Stuff!') - ->willReturn(1); - $view->expects($this->once()) - ->method('render') - ->with('test/template.tpl', ['dev' => true]) - ->willReturn('Rendered Stuff!'); + $this->setExpects($mailer, 'send', ['foo@bar.baz', 'Lorem dolor', 'Rendered Stuff!'], 1); + $this->setExpects($view, 'render', ['test/template.tpl', ['dev' => true]], 'Rendered Stuff!'); $return = $mailer->sendView('foo@bar.baz', 'Lorem dolor', 'test/template.tpl', ['dev' => true]); $this->equalTo(1, $return); } /** + * @covers \Engelsystem\Mail\EngelsystemMailer::sendViewTranslated + */ + public function testSendViewTranslated() + { + $this->initDatabase(); + + $settings = new Settings([ + 'language' => 'de_DE', + 'theme' => '', + ]); + $contact = new Contact(['email' => null]); + $user = new User([ + 'id' => 42, + 'name' => 'username', + 'email' => 'foo@bar.baz', + 'password' => '', + 'api_key' => '', + ]); + $user->save(); + $settings->user()->associate($user)->save(); + $contact->user()->associate($user)->save(); + + /** @var Renderer|MockObject $view */ + $view = $this->createMock(Renderer::class); + /** @var SwiftMailer|MockObject $swiftMailer */ + $swiftMailer = $this->createMock(SwiftMailer::class); + /** @var Translator|MockObject $translator */ + $translator = $this->createMock(Translator::class); + + /** @var EngelsystemMailer|MockObject $mailer */ + $mailer = $this->getMockBuilder(EngelsystemMailer::class) + ->setConstructorArgs(['mailer' => $swiftMailer, 'view' => $view, 'translation' => $translator]) + ->onlyMethods(['sendView']) + ->getMock(); + + $this->setExpects($mailer, 'sendView', ['foo@bar.baz', 'Lorem dolor', 'test/template.tpl', ['dev' => true]], 1); + $this->setExpects($translator, 'getLocales', null, ['de_DE' => 'de_DE', 'en_US' => 'en_US']); + $this->setExpects($translator, 'getLocale', null, 'en_US'); + $this->setExpects($translator, 'translate', ['translatable.text'], 'Lorem dolor'); + $translator->expects($this->exactly(2)) + ->method('setLocale') + ->withConsecutive(['de_DE'], ['en_US']); + + $return = $mailer->sendViewTranslated( + $user, + 'translatable.text', + 'test/template.tpl', + ['dev' => true], + 'de_DE' + ); + $this->equalTo(1, $return); + } + + /** * @covers \Engelsystem\Mail\EngelsystemMailer::getSubjectPrefix * @covers \Engelsystem\Mail\EngelsystemMailer::send * @covers \Engelsystem\Mail\EngelsystemMailer::setSubjectPrefix @@ -50,32 +105,12 @@ class EngelsystemMailerTest extends TestCase $message = $this->createMock(SwiftMessage::class); /** @var SwiftMailer|MockObject $swiftMailer */ $swiftMailer = $this->createMock(SwiftMailer::class); - $swiftMailer->expects($this->once()) - ->method('createMessage') - ->willReturn($message); - $swiftMailer->expects($this->once()) - ->method('send') - ->willReturn(1); - - $message->expects($this->once()) - ->method('setTo') - ->with(['to@xam.pel']) - ->willReturn($message); - - $message->expects($this->once()) - ->method('setFrom') - ->with('foo@bar.baz', 'Lorem Ipsum') - ->willReturn($message); - - $message->expects($this->once()) - ->method('setSubject') - ->with('[Mail test] Foo Bar') - ->willReturn($message); - - $message->expects($this->once()) - ->method('setBody') - ->with('Lorem Ipsum!') - ->willReturn($message); + $this->setExpects($swiftMailer, 'createMessage', null, $message); + $this->setExpects($swiftMailer, 'send', null, 1); + $this->setExpects($message, 'setTo', [['to@xam.pel']], $message); + $this->setExpects($message, 'setFrom', ['foo@bar.baz', 'Lorem Ipsum'], $message); + $this->setExpects($message, 'setSubject', ['[Mail test] Foo Bar'], $message); + $this->setExpects($message, 'setBody', ['Lorem Ipsum!'], $message); $mailer = new EngelsystemMailer($swiftMailer); $mailer->setFromAddress('foo@bar.baz'); diff --git a/tests/Unit/Models/EventConfigTest.php b/tests/Unit/Models/EventConfigTest.php index e2ab5d10..18d27007 100644 --- a/tests/Unit/Models/EventConfigTest.php +++ b/tests/Unit/Models/EventConfigTest.php @@ -5,7 +5,7 @@ namespace Engelsystem\Test\Unit\Models; use Carbon\Carbon; use Engelsystem\Models\EventConfig; use Engelsystem\Test\Unit\HasDatabase; -use PHPUnit\Framework\TestCase; +use Engelsystem\Test\Unit\TestCase; class EventConfigTest extends TestCase { @@ -102,7 +102,8 @@ class EventConfigTest extends TestCase */ protected function getEventConfig() { - return new class extends EventConfig { + return new class extends EventConfig + { /** * @param string $value * @param string $type @@ -122,6 +123,7 @@ class EventConfigTest extends TestCase */ protected function setUp(): void { + parent::setUp(); $this->initDatabase(); } } diff --git a/tests/Unit/Models/LogEntryTest.php b/tests/Unit/Models/LogEntryTest.php index 0a0efa3c..4b772cd0 100644 --- a/tests/Unit/Models/LogEntryTest.php +++ b/tests/Unit/Models/LogEntryTest.php @@ -4,7 +4,7 @@ namespace Engelsystem\Test\Unit\Models; use Engelsystem\Models\LogEntry; use Engelsystem\Test\Unit\HasDatabase; -use PHPUnit\Framework\TestCase; +use Engelsystem\Test\Unit\TestCase; use Psr\Log\LogLevel; class LogEntryTest extends TestCase @@ -38,6 +38,7 @@ class LogEntryTest extends TestCase */ protected function setUp(): void { + parent::setUp(); $this->initDatabase(); } } diff --git a/tests/Unit/Models/User/HasUserModelTest.php b/tests/Unit/Models/User/HasUserModelTest.php index 58c01e1e..4f6da9ad 100644 --- a/tests/Unit/Models/User/HasUserModelTest.php +++ b/tests/Unit/Models/User/HasUserModelTest.php @@ -5,8 +5,8 @@ namespace Engelsystem\Test\Unit\Models; use Engelsystem\Models\User\HasUserModel; use Engelsystem\Test\Unit\HasDatabase; use Engelsystem\Test\Unit\Models\User\Stub\HasUserModelImplementation; +use Engelsystem\Test\Unit\TestCase; use Illuminate\Database\Eloquent\Relations\BelongsTo; -use PHPUnit\Framework\TestCase; class HasUserModelTest extends TestCase { @@ -28,6 +28,7 @@ class HasUserModelTest extends TestCase */ protected function setUp(): void { + parent::setUp(); $this->initDatabase(); } } diff --git a/tests/Unit/Models/User/UserTest.php b/tests/Unit/Models/User/UserTest.php index 0e17d137..3e793832 100644 --- a/tests/Unit/Models/User/UserTest.php +++ b/tests/Unit/Models/User/UserTest.php @@ -10,7 +10,7 @@ use Engelsystem\Models\User\Settings; use Engelsystem\Models\User\State; use Engelsystem\Models\User\User; use Engelsystem\Test\Unit\HasDatabase; -use PHPUnit\Framework\TestCase; +use Engelsystem\Test\Unit\TestCase; class UserTest extends TestCase { @@ -95,6 +95,7 @@ class UserTest extends TestCase */ protected function setUp(): void { + parent::setUp(); $this->initDatabase(); } } diff --git a/tests/Unit/Renderer/RendererServiceProviderTest.php b/tests/Unit/Renderer/RendererServiceProviderTest.php index 224e36d4..e655284d 100644 --- a/tests/Unit/Renderer/RendererServiceProviderTest.php +++ b/tests/Unit/Renderer/RendererServiceProviderTest.php @@ -67,15 +67,13 @@ class RendererServiceProviderTest extends ServiceProviderTest $app = $this->getApp(['get', 'tagged']); - $engines = [$engine1, $engine2]; - $this->setExpects($app, 'get', ['renderer'], $renderer); - $this->setExpects($app, 'tagged', ['renderer.engine'], $engines); + $this->setExpects($app, 'tagged', ['renderer.engine'], [$engine1, $engine2]); - $invocation = $renderer - ->expects($this->exactly(count($engines))) - ->method('addRenderer'); - call_user_func_array([$invocation, 'withConsecutive'], $engines); + $renderer + ->expects($this->exactly(2)) + ->method('addRenderer') + ->withConsecutive([$engine1], [$engine2]); $serviceProvider = new RendererServiceProvider($app); $serviceProvider->boot(); diff --git a/tests/Unit/Renderer/Twig/Extensions/LegacyTest.php b/tests/Unit/Renderer/Twig/Extensions/LegacyTest.php index b6c19d14..7190c979 100644 --- a/tests/Unit/Renderer/Twig/Extensions/LegacyTest.php +++ b/tests/Unit/Renderer/Twig/Extensions/LegacyTest.php @@ -26,6 +26,7 @@ class LegacyTest extends ExtensionTest $this->assertExtensionExists('menuUserHints', 'header_render_hints', $functions, $isSafeHtml); $this->assertExtensionExists('menuUserSubmenu', 'make_user_submenu', $functions, $isSafeHtml); $this->assertExtensionExists('page', [$extension, 'getPage'], $functions); + $this->assertExtensionExists('msg', 'msg', $functions, $isSafeHtml); } /** diff --git a/tests/Unit/Renderer/TwigServiceProviderTest.php b/tests/Unit/Renderer/TwigServiceProviderTest.php index 86dee1de..ee4cd971 100644 --- a/tests/Unit/Renderer/TwigServiceProviderTest.php +++ b/tests/Unit/Renderer/TwigServiceProviderTest.php @@ -82,7 +82,7 @@ class TwigServiceProviderTest extends ServiceProviderTest $twig->expects($this->exactly(2)) ->method('addExtension') - ->withConsecutive($firsExtension, $secondExtension); + ->withConsecutive([$firsExtension], [$secondExtension]); $serviceProvider = new TwigServiceProvider($app); $serviceProvider->boot(); diff --git a/tests/Unit/TestCase.php b/tests/Unit/TestCase.php index d09104d4..dba8c989 100644 --- a/tests/Unit/TestCase.php +++ b/tests/Unit/TestCase.php @@ -2,18 +2,22 @@ namespace Engelsystem\Test\Unit; -use PHPUnit\Framework\MockObject\Matcher\InvokedRecorder; +use Engelsystem\Application; use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\MockObject\Rule\InvocationOrder; use PHPUnit\Framework\TestCase as PHPUnitTestCase; abstract class TestCase extends PHPUnitTestCase { + /** @var Application */ + protected $app; + /** * @param MockObject $object * @param string $method * @param array $arguments * @param mixed $return - * @param InvokedRecorder $times + * @param InvocationOrder $times */ protected function setExpects($object, $method, $arguments = null, $return = null, $times = null) { @@ -34,4 +38,12 @@ abstract class TestCase extends PHPUnitTestCase $invocation->willReturn($return); } } + + /** + * Called before each test run + */ + protected function setUp(): void + { + $this->app = new Application(__DIR__ . '/../../'); + } } |