You are here

class FileLogTest in File Log 8

Same name and namespace in other branches
  1. 2.0.x tests/src/Unit/FileLogTest.php \Drupal\Tests\filelog\Unit\FileLogTest

Test the file logger.

@group filelog

Hierarchy

Expanded class hierarchy of FileLogTest

File

tests/src/Unit/FileLogTest.php, line 20

Namespace

Drupal\Tests\filelog\Unit
View source
class FileLogTest extends FileLogTestBase {

  /**
   * A mock of the token service.
   *
   * @var \Drupal\Core\Utility\Token
   */
  protected $token;

  /**
   * The logger.log_message_parser service.
   *
   * @var \Drupal\Core\Logger\LogMessageParserInterface
   */
  protected $logMessageParser;

  /**
   * A mock of the datetime.time service.
   *
   * @var \Drupal\Component\Datetime\TimeInterface
   */
  protected $time;

  /**
   * The virtual file-system.
   *
   * @var \org\bovigo\vfs\vfsStreamDirectory
   */
  protected $virtualFileSystem;

  /**
   * A mock of the file_system service.
   *
   * @var \Drupal\Core\File\FileSystemInterface
   */
  protected $fileSystem;

  /**
   * {@inheritdoc}
   */
  protected function setUp() : void {
    parent::setUp();
    $this->token = $this
      ->getMockBuilder(Token::class)
      ->disableOriginalConstructor()
      ->getMock();
    $this->token
      ->method('replace')
      ->willReturnCallback([
      static::class,
      'tokenReplace',
    ]);
    $this->time = $this
      ->createMock(TimeInterface::class);
    $this->time
      ->method('getRequestTime')
      ->willReturn($_SERVER['REQUEST_TIME']);
    $this->logMessageParser = new LogMessageParser();
  }

  /**
   * Test a particular configuration.
   *
   * Ensure that it logs the correct events.
   *
   * @param array $config
   *   The filelog settings.
   * @param array $events
   *   The events to be logged.
   * @param string $expected
   *   The expected content of the log file after the test.
   *
   * @dataProvider providerFileLog
   */
  public function testFileLog(array $config, array $events, $expected = '') : void {

    /** @var \Drupal\Core\Config\ConfigFactoryInterface $configFactory */
    $configFactory = $this
      ->getConfigFactoryStub([
      'filelog.settings' => $config,
    ]);

    /** @var \Drupal\Core\State\StateInterface|\PHPUnit_Framework_MockObject_MockObject $state */
    $state_data = [
      'filelog.rotation' => 0,
    ];
    $state = $this
      ->createMock(StateInterface::class);
    $state
      ->method('get')
      ->willReturnCallback(static function ($key) use (&$state_data) {
      return $state_data[$key];
    });
    $state
      ->method('set')
      ->willReturnCallback(static function ($key, $value) use (&$state_data) {
      $state_data[$key] = $value;
    });
    $logger = new FileLog($configFactory, $state, $this->token, $this->time, $this->logMessageParser, new LogFileManager($configFactory, $this->fileSystem));
    foreach ($events as $event) {
      $logger
        ->log($event['level'], $event['message'], $event['context']);
    }

    // Read log output and remove file for the next test.
    $content = '';
    if ($this->virtualFileSystem
      ->hasChild(LogFileManager::FILENAME)) {
      $content = file_get_contents($this->virtualFileSystem
        ->getChild(LogFileManager::FILENAME)
        ->url());
      $this->virtualFileSystem
        ->removeChild(LogFileManager::FILENAME);
    }
    $this
      ->assertEquals($expected, $content);

    // Check that the timestamp was saved if and only if a log was created.
    $timestamp = $state
      ->get('filelog.rotation');
    $this
      ->assertEquals($content ? $_SERVER['REQUEST_TIME'] : 0, $timestamp);
  }

  /**
   * Provide data for the level-checking test.
   *
   * @return array
   *   All datasets for ::testFileLog().
   */
  public function providerFileLog() : array {
    $config = [
      'enabled' => TRUE,
      'location' => 'vfs://filelog',
      'level' => 7,
      'channels_type' => 'exclude',
      'channels' => [],
      'format' => '[log:level] [log:message]',
    ];
    $levels = LogMessage::getLevels();
    $events = [];
    $messages = [];
    for ($i = 0; $i <= 7; $i++) {
      $events[] = [
        'level' => $i,
        'message' => "This is message @i.\n LD5}5>~\\8AiU * VH",
        'context' => [
          '@i' => $i,
          'timestamp' => 0,
          'channel' => "channel_{$i}",
        ],
      ];
      $messages[] = $levels[$i] . " This is message {$i}.\\n LD5}5>~\\8AiU * VH";
    }
    $data = [];
    for ($i = 0, $iMax = count($levels); $i <= $iMax; $i++) {
      $expected = implode("\n", array_slice($messages, 0, $i + 1)) . "\n";
      $data[$i] = [
        'config' => [
          'level' => $i,
        ] + $config,
        'events' => $events,
        'expected' => $expected,
      ];
    }
    $data[] = [
      'config' => [
        'enabled' => FALSE,
      ] + $config,
      'events' => $events,
      'expected' => '',
    ];
    $data[] = [
      'config' => [
        'channels_type' => 'include',
      ] + $config,
      'events' => $events,
      'expected' => '',
    ];
    $data[] = [
      'config' => [
        'channels_type' => 'include',
        'channels' => [
          'channel_3',
        ],
      ] + $config,
      'events' => $events,
      'expected' => $messages[3] . "\n",
    ];
    $data[] = [
      'config' => [
        'channels' => [
          'channel_3',
        ],
      ] + $config,
      'events' => $events,
      'expected' => implode("\n", array_slice($messages, 0, 3) + array_slice($messages, 4, 4, TRUE)) . "\n",
    ];
    return $data;
  }

  /**
   * A very primitive mock for the token service.
   *
   * The full token integration is tested separately.
   *
   * @param string $text
   *   The text to be replaced.
   * @param array $data
   *   The placeholders.
   *
   * @return string
   *   The formatted text.
   */
  public static function tokenReplace($text, array $data) : string {

    /** @var \Drupal\filelog\LogMessage $message */
    $message = $data['log'];
    return strtr($text, [
      '[log:message]' => $message
        ->getText(),
      '[log:level]' => $message
        ->getLevel(),
    ]);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
FileLogTest::$fileSystem protected property A mock of the file_system service.
FileLogTest::$logMessageParser protected property The logger.log_message_parser service.
FileLogTest::$time protected property A mock of the datetime.time service.
FileLogTest::$token protected property A mock of the token service.
FileLogTest::$virtualFileSystem protected property The virtual file-system. Overrides FileLogTestBase::$virtualFileSystem
FileLogTest::providerFileLog public function Provide data for the level-checking test.
FileLogTest::setUp protected function Overrides FileLogTestBase::setUp
FileLogTest::testFileLog public function Test a particular configuration.
FileLogTest::tokenReplace public static function A very primitive mock for the token service.
PhpunitCompatibilityTrait::getMock Deprecated public function Returns a mock object for the specified class using the available method.
PhpunitCompatibilityTrait::setExpectedException Deprecated public function Compatibility layer for PHPUnit 6 to support PHPUnit 4 code.
UnitTestCase::$randomGenerator protected property The random generator.
UnitTestCase::$root protected property The app root. 1
UnitTestCase::assertArrayEquals protected function Asserts if two arrays are equal by sorting them first.
UnitTestCase::getBlockMockWithMachineName Deprecated protected function Mocks a block with a block plugin. 1
UnitTestCase::getClassResolverStub protected function Returns a stub class resolver.
UnitTestCase::getConfigFactoryStub public function Returns a stub config factory that behaves according to the passed array.
UnitTestCase::getConfigStorageStub public function Returns a stub config storage that returns the supplied configuration.
UnitTestCase::getContainerWithCacheTagsInvalidator protected function Sets up a container with a cache tags invalidator.
UnitTestCase::getRandomGenerator protected function Gets the random generator for the utility methods.
UnitTestCase::getStringTranslationStub public function Returns a stub translation manager that just returns the passed string.
UnitTestCase::randomMachineName public function Generates a unique random string containing letters and numbers.