diff --git a/src/Logger/Logger.php b/src/Logger/Logger.php index 21103db7..2b5bcdbe 100644 --- a/src/Logger/Logger.php +++ b/src/Logger/Logger.php @@ -14,7 +14,7 @@ use Throwable; class Logger extends AbstractLogger { /** @var array */ - protected $allowedLevels = [ // phpcs:ignore + protected array $allowedLevels = [ LogLevel::ALERT, LogLevel::CRITICAL, LogLevel::DEBUG, diff --git a/tests/Feature/Logger/LoggerTest.php b/tests/Feature/Logger/LoggerTest.php deleted file mode 100644 index 93a744dd..00000000 --- a/tests/Feature/Logger/LoggerTest.php +++ /dev/null @@ -1,178 +0,0 @@ -assertInstanceOf(LoggerInterface::class, $this->getLogger()); - } - - /** - * @return string[][] - */ - public function provideLogLevels(): array - { - return [ - [LogLevel::ALERT], - [LogLevel::CRITICAL], - [LogLevel::DEBUG], - [LogLevel::EMERGENCY], - [LogLevel::ERROR], - [LogLevel::INFO], - [LogLevel::NOTICE], - [LogLevel::WARNING], - ]; - } - - /** - * @covers \Engelsystem\Logger\Logger::log - * @dataProvider provideLogLevels - */ - public function testAllLevels(string $level): void - { - LogEntry::query()->truncate(); - $logger = $this->getLogger(); - - $logger->log($level, 'First log message'); - $logger->{$level}('Second log message'); - - $entries = LogEntry::all(); - $this->assertCount(2, $entries); - } - - /** - * @covers \Engelsystem\Logger\Logger::log - */ - public function testContextReplacement(): void - { - LogEntry::query()->truncate(); - $logger = $this->getLogger(); - - $logger->log(LogLevel::INFO, 'My username is {username}', ['username' => 'Foo']); - - $entry = $this->getLastEntry(); - $this->assertEquals('My username is Foo', $entry['message']); - $this->assertEquals(LogLevel::INFO, $entry['level']); - } - - /** - * @return mixed[][] - */ - public function provideContextReplaceValues(): array - { - return [ - ['Data and {context}', [], 'Data and {context}'], - ['Data and {context}', ['context' => null], 'Data and '], - ['Data and {context}', ['context' => new stdClass()], 'Data and {context}'], - ['Some user asked: {question}', ['question' => 'Foo?'], 'Some user asked: Foo?'], - ]; - } - - /** - * @covers \Engelsystem\Logger\Logger::interpolate - * @covers \Engelsystem\Logger\Logger::log - * @dataProvider provideContextReplaceValues - * - * @param string[] $context - */ - public function testContextReplaceValues(string $message, array $context, string $expected): void - { - $logger = $this->getLogger(); - $logger->log(LogLevel::INFO, $message, $context); - - $entry = $this->getLastEntry(); - $this->assertEquals($expected, $entry['message']); - } - - /** - * @covers \Engelsystem\Logger\Logger::log - */ - public function testContextToString(): void - { - LogEntry::query()->truncate(); - $logger = $this->getLogger(); - - $mock = $this->getMockBuilder(stdClass::class) - ->addMethods(['__toString']) - ->getMock(); - - $mock->expects($this->atLeastOnce()) - ->method('__toString') - ->will($this->returnValue('FooBar')); - - $logger->log(LogLevel::INFO, 'Some data and {context}', ['context' => $mock]); - - $entry = $this->getLastEntry(); - $this->assertEquals('Some data and FooBar', $entry['message']); - } - - /** - * @covers \Engelsystem\Logger\Logger::checkLevel - * @covers \Engelsystem\Logger\Logger::log - */ - public function testThrowExceptionOnInvalidLevel(): void - { - $logger = $this->getLogger(); - - $this->expectException(InvalidArgumentException::class); - $logger->log('This log level should never be defined', 'Some message'); - } - - /** - * @covers \Engelsystem\Logger\Logger::formatException - * @covers \Engelsystem\Logger\Logger::log - */ - public function testWithException(): void - { - $logger = $this->getLogger(); - - $logger->log(LogLevel::CRITICAL, 'Some random message', ['exception' => new Exception('Oops', 42)]); - $line = __LINE__ - 1; - - $entry = $this->getLastEntry(); - $this->assertStringContainsString('Some random message', $entry['message']); - $this->assertStringContainsString('Oops', $entry['message']); - $this->assertStringContainsString('42', $entry['message']); - $this->assertStringContainsString(__FILE__, $entry['message']); - $this->assertStringContainsString((string) $line, $entry['message']); - $this->assertStringContainsString(__FUNCTION__, $entry['message']); - } - - protected function getLastEntry(): LogEntry - { - return LogEntry::all()->last(); - } - - /** - * Cleanup - */ - protected function tearDown(): void - { - LogEntry::query()->truncate(); - } -} diff --git a/tests/Feature/Model/LogEntryTest.php b/tests/Feature/Model/LogEntryTest.php deleted file mode 100644 index ad7ad0b3..00000000 --- a/tests/Feature/Model/LogEntryTest.php +++ /dev/null @@ -1,60 +0,0 @@ - LogLevel::INFO, - 'Some test content' => LogLevel::ERROR, - 'Foo bar bartz!' => LogLevel::INFO, - 'Someone did something?' => LogLevel::NOTICE, - 'This is a Test!' => LogLevel::INFO, - 'I\'m verbose notice!' => LogLevel::DEBUG, - 'The newest stuff!!' => LogLevel::ERROR, - ] as $message => $level - ) { - $entry = new LogEntry(['level' => $level, 'message' => $message]); - $entry->save(); - } - - $model = new LogEntry(); - - $return = $model->filter(); - $this->assertCount(7, $return); - - /** @var LogEntry $first */ - $first = $return->first(); - - $this->assertEquals('The newest stuff!!', $first->message); - - $return = $model->filter(LogLevel::INFO); - $this->assertCount(3, $return); - - $return = $model->filter('notice'); - $this->assertCount(2, $return); - - $return = $model->filter('bartz'); - $this->assertCount(1, $return); - } - - /** - * This method is called before a test is executed. - */ - protected function setUp(): void - { - LogEntry::query()->truncate(); - } -} diff --git a/tests/Unit/Logger/LoggerTest.php b/tests/Unit/Logger/LoggerTest.php index 5e8e8361..329a8e1b 100644 --- a/tests/Unit/Logger/LoggerTest.php +++ b/tests/Unit/Logger/LoggerTest.php @@ -6,76 +6,161 @@ namespace Engelsystem\Test\Unit\Logger; use Engelsystem\Logger\Logger; use Engelsystem\Models\LogEntry; +use Engelsystem\Test\Unit\HasDatabase; use Engelsystem\Test\Unit\ServiceProviderTest; -use InvalidArgumentException; -use PHPUnit\Framework\MockObject\MockObject; +use Exception; +use Psr\Log\InvalidArgumentException; +use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; +use stdClass; class LoggerTest extends ServiceProviderTest { + use HasDatabase; + /** * @covers \Engelsystem\Logger\Logger::__construct - * @covers \Engelsystem\Logger\Logger::log */ - public function testLog(): void + public function testImplements(): void { - /** @var LogEntry|MockObject $logEntry */ - $logEntry = $this->getMockBuilder(LogEntry::class) - ->addMethods(['create']) - ->getMock(); - $logEntry->expects($this->once()) - ->method('create') - ->with(['level' => LogLevel::INFO, 'message' => 'I\'m an information!']); + $this->assertInstanceOf(LoggerInterface::class, new Logger(new LogEntry())); + } - $logger = new Logger($logEntry); + /** + * @return string[][] + */ + public function provideLogLevels(): array + { + return [ + [LogLevel::ALERT], + [LogLevel::CRITICAL], + [LogLevel::DEBUG], + [LogLevel::EMERGENCY], + [LogLevel::ERROR], + [LogLevel::INFO], + [LogLevel::NOTICE], + [LogLevel::WARNING], + ]; + } - $logger->log(LogLevel::INFO, 'I\'m an information!'); + /** + * @covers \Engelsystem\Logger\Logger::log + * @dataProvider provideLogLevels + */ + public function testAllLevels(string $level): void + { + $logger = new Logger(new LogEntry()); + + $logger->log($level, 'First log message'); + $logger->{$level}('Second log message'); + + $entries = LogEntry::all(); + $this->assertCount(2, $entries); } /** * @covers \Engelsystem\Logger\Logger::log - * @covers \Engelsystem\Logger\Logger::checkLevel */ - public function testCheckLevel(): void + public function testContextReplacement(): void { - /** @var LogEntry|MockObject $logEntry */ - $logEntry = $this->createMock(LogEntry::class); - $logger = new Logger($logEntry); + $logger = new Logger(new LogEntry()); + + $logger->log(LogLevel::INFO, 'My username is {username}', ['username' => 'Foo']); + + /** @var LogEntry $entry */ + $entry = LogEntry::find(1); + $this->assertEquals('My username is Foo', $entry->message); + $this->assertEquals(LogLevel::INFO, $entry['level']); + } + + /** + * @return array> + */ + public function provideContextReplaceValues(): array + { + return [ + ['Data and {context}', [], 'Data and {context}'], + ['Data and {context}', ['context' => null], 'Data and '], + ['Data and {context}', ['context' => new stdClass()], 'Data and {context}'], + ['Some user asked: {question}', ['question' => 'Foo?'], 'Some user asked: Foo?'], + ]; + } + + /** + * @covers \Engelsystem\Logger\Logger::interpolate + * @covers \Engelsystem\Logger\Logger::log + * @dataProvider provideContextReplaceValues + * + * @param string[] $context + */ + public function testContextReplaceValues(string $message, array $context, string $expected): void + { + $logger = new Logger(new LogEntry()); + $logger->log(LogLevel::INFO, $message, $context); + + /** @var LogEntry $entry */ + $entry = LogEntry::find(1); + $this->assertEquals($expected, $entry->message); + } + + /** + * @covers \Engelsystem\Logger\Logger::log + */ + public function testContextToString(): void + { + $logger = new Logger(new LogEntry()); + + $mock = $this->getMockBuilder(stdClass::class) + ->addMethods(['__toString']) + ->getMock(); + + $mock->expects($this->atLeastOnce()) + ->method('__toString') + ->will($this->returnValue('FooBar')); + + $logger->log(LogLevel::INFO, 'Some data and {context}', ['context' => $mock]); + + /** @var LogEntry $entry */ + $entry = LogEntry::find(1); + $this->assertEquals('Some data and FooBar', $entry->message); + } + + /** + * @covers \Engelsystem\Logger\Logger::checkLevel + * @covers \Engelsystem\Logger\Logger::log + */ + public function testThrowExceptionOnInvalidLevel(): void + { + $logger = new Logger(new LogEntry()); $this->expectException(InvalidArgumentException::class); - $logger->log('FooBar', 'Random Stuff'); + $logger->log('This log level should never be defined', 'Some message'); } /** - * @covers \Engelsystem\Logger\Logger::interpolate + * @covers \Engelsystem\Logger\Logger::formatException + * @covers \Engelsystem\Logger\Logger::log */ - public function testInterpolate(): void + public function testWithException(): void { - /** @var LogEntry|MockObject $logEntry */ - $logEntry = $this->getMockBuilder(LogEntry::class) - ->addMethods(['create']) - ->getMock(); - $logEntry->expects($this->exactly(3)) - ->method('create') - ->withConsecutive( - [['level' => LogLevel::DEBUG, 'message' => 'User: Foo']], - [['level' => LogLevel::NOTICE, 'message' => 'User: {user}']], - [['level' => LogLevel::NOTICE, 'message' => 'User: Bar']] - ); + $logger = new Logger(new LogEntry()); - $logger = new Logger($logEntry); + $logger->log(LogLevel::CRITICAL, 'Some random message', ['exception' => new Exception('Oops', 42)]); + $line = __LINE__ - 1; + /** @var LogEntry $entry */ + $entry = LogEntry::find(1); + $this->assertStringContainsString('Some random message', $entry->message); + $this->assertStringContainsString('Oops', $entry->message); + $this->assertStringContainsString('42', $entry->message); + $this->assertStringContainsString(__FILE__, $entry->message); + $this->assertStringContainsString((string) $line, $entry->message); + $this->assertStringContainsString(__FUNCTION__, $entry->message); + } - $logger->log(LogLevel::DEBUG, 'User: {user}', ['user' => 'Foo']); - $logger->log(LogLevel::NOTICE, 'User: {user}', ['user' => ['name' => 'Lorem']]); - $logger->log(LogLevel::NOTICE, 'User: {user}', [ - 'user' => - new class - { - public function __toString(): string - { - return 'Bar'; - } - }, - ]); + public function setUp(): void + { + parent::setUp(); + + $this->initDatabase(); } } diff --git a/tests/Unit/Models/LogEntryTest.php b/tests/Unit/Models/LogEntryTest.php index 5875f388..4aca5d83 100644 --- a/tests/Unit/Models/LogEntryTest.php +++ b/tests/Unit/Models/LogEntryTest.php @@ -19,17 +19,30 @@ class LogEntryTest extends ModelTest 'I\'m an info' => LogLevel::INFO, '*Insert explosion here*' => LogLevel::EMERGENCY, 'Tracing along' => LogLevel::DEBUG, - 'Oops' => LogLevel::ERROR, + 'Oops,no notice given' => LogLevel::NOTICE, 'It\'s happening' => LogLevel::INFO, 'Something is wrong' => LogLevel::ERROR, 'Ohi' => LogLevel::INFO, + 'I\'m no notice' => LogLevel::CRITICAL, + 'Just here to warn you!' => LogLevel::WARNING, + 'The newest stuff!!' => LogLevel::ALERT, ] as $message => $level ) { (new LogEntry(['level' => $level, 'message' => $message]))->save(); } - $this->assertCount(7, LogEntry::filter()); + $this->assertCount(10, LogEntry::filter()); $this->assertCount(3, LogEntry::filter(LogLevel::INFO)); $this->assertCount(1, LogEntry::filter('Oops')); + + /** @var LogEntry $first */ + $first = LogEntry::filter()->first(); + $this->assertEquals('The newest stuff!!', $first->message); + + $return = LogEntry::filter('notice'); + $this->assertCount(2, $return); + + $return = LogEntry::filter('Ohi'); + $this->assertCount(1, $return); } }