* @copyright 2016 - 2021 Timothy J. Warren * @license http://www.opensource.org/licenses/mit-license.html MIT License * @version 3.2.0 * @link https://git.timshomepage.net/timw4mail/banker */ namespace Aviat\Banker\Tests; use Aviat\Banker\Pool; use Aviat\Banker\Teller; use Aviat\Banker\Exception\InvalidArgumentException; use Monolog\Handler\SyslogHandler; use Monolog\Logger; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; class TellerTest extends TestCase { protected Teller $teller; private array $testValues = [ 'foo' => 24, 'bar' => '87', 'baz' => [1, 2, 3], 'a' => TRUE, 'b' => 1, 'c' => FALSE, 'd' => 0, 'e' => NULL, 'f' => [ 'a' => [ 'b' => 'c', 'd' => [1, 2, 3] ] ] ]; public function setUp(): void { $this->teller = new Teller([ 'driver' => 'null', 'connection' => [] ]); // Call clear to make sure we are working from a clean slate to start $this->teller->clear(); } public function testGetDefaultLogger(): void { $friend = new Friend($this->teller); $driverFriend = new Friend($friend->driver); // Check that a valid logger is set $this->assertInstanceOf(LoggerInterface::class, $friend->getLogger(), "Logger exists after being set"); $this->assertInstanceOf(LoggerInterface::class, $driverFriend->getLogger(), "Logger exists on driver after being set"); // Make sure we get the default Null logger $this->assertTrue(is_a($friend->getLogger(), NullLogger::class)); $this->assertTrue(is_a($driverFriend->getLogger(), NullLogger::class)); } public function testSetLoggerInConstructor(): void { $logger = new Logger('test'); $logger->pushHandler(new SyslogHandler('warning', LOG_USER, Logger::WARNING)); $teller = new Teller([ 'driver' => 'null', 'connection' => [], ], $logger); $friend = new Friend($teller); $driverFriend = new Friend($friend->driver); // Check that a valid logger is set $this->assertInstanceOf(LoggerInterface::class, $friend->getLogger(), "Logger exists after being set"); $this->assertInstanceOf(LoggerInterface::class, $driverFriend->getLogger(), "Logger exists on driver after being set"); // Make sure we aren't just getting the default Null logger $this->assertFalse(is_a($friend->getLogger(), NullLogger::class)); $this->assertFalse(is_a($driverFriend->getLogger(), NullLogger::class)); } public function testGetSetLogger(): void { $logger = new Logger('test'); $logger->pushHandler(new SyslogHandler('warning2',LOG_USER, Logger::WARNING)); $this->teller->setLogger($logger); $friend = new Friend($this->teller); $driverFriend = new Friend($friend->driver); // Check that a valid logger is set $this->assertInstanceOf(LoggerInterface::class, $friend->getLogger(), "Logger exists after being set"); $this->assertInstanceOf(LoggerInterface::class, $driverFriend->getLogger(), "Logger exists on driver after being set"); // Make sure we aren't just getting the default Null logger $this->assertFalse(is_a($friend->getLogger(), NullLogger::class)); $this->assertFalse(is_a($driverFriend->getLogger(), NullLogger::class)); } public function testGetSet(): void { foreach ($this->testValues as $key => $value) { $this->assertTrue($this->teller->set($key, $value, 0), "Failed to set value for key: {$key}"); $received = $this->teller->get($key); $this->assertEquals($value, $received, "Invalid value returned for key: {$key}"); } } public function testGetSetMultiple(): void { $this->assertTrue($this->teller->setMultiple($this->testValues)); $received = $this->teller->getMultiple(array_keys($this->testValues)); $this->assertEquals($this->testValues, $received); } public function testClear(): void { $data = [ 'foo' => 'bar', 'bar' => 'baz', 'foobar' => 'foobarbaz' ]; // Set up some data $this->teller->setMultiple($data); foreach($data as $key => $val) { $this->assertTrue($this->teller->has($key)); $this->assertEquals($val, $this->teller->get($key)); } // Now we clear it all! $this->teller->clear(); foreach($data as $key => $val) { $this->assertFalse($this->teller->has($key)); $this->assertNull($this->teller->get($key)); } } public function testDelete(): void { $this->teller->setMultiple($this->testValues); $this->assertTrue($this->teller->delete('foo')); $this->assertFalse($this->teller->has('foo')); // Make sure we get the default value for the key $this->assertEquals('Q', $this->teller->get('foo', 'Q')); } public function testDeleteMultiple(): void { $this->teller->setMultiple($this->testValues); $deleteKeys = ['foo', 'bar', 'baz']; $hasKeys = ['a', 'b', 'c', 'd', 'e', 'f']; $this->assertTrue($this->teller->deleteMultiple($deleteKeys)); array_walk($deleteKeys, fn ($key) => $this->assertFalse($this->teller->has($key))); array_walk($hasKeys, fn ($key) => $this->assertTrue($this->teller->has($key))); } public function testBadKeyType(): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Cache key must be a string.'); $this->teller->get(546567); } public function testBadKeysType (): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Keys must be an array or a traversable object'); $keys = (object)[]; $this->teller->getMultiple($keys); } /** * @dataProvider keyValidationTests */ public function testKeyValidation($key): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid characters in cache key'); $this->teller->get($key); } public function keyValidationTests(): array { // {}()/@:\\\ return [ ['key' => '{}()/@:\\'], ['key' => 'a: b'], ['key' => 'a/b'], ['key' => '{'], ['key' => 'a@b'], ]; } }