clean install

This commit is contained in:
2024-12-10 15:08:16 +01:00
commit e14eb2d8fd
31193 changed files with 3555714 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
id: default
label: default
description: 'Test log type'
name_pattern: '[log:id:value]'
langcode: en
workflow: log_default
new_revision: TRUE

View File

@@ -0,0 +1,7 @@
id: name_pattern
label: Name Pattern
description: 'Test log type (with name pattern)'
name_pattern: '[log:id:value] [log:status:value]'
langcode: en
workflow: log_default
new_revision: TRUE

View File

@@ -0,0 +1,14 @@
name: 'Log module tests'
type: module
description: 'Support module for log testing.'
package: Testing
core_version_requirement: ^9 || ^10 || ^11
dependencies:
- log:log
- token:token
# Information added by Drupal.org packaging script on 2024-07-18
version: '2.3.0'
project: 'log'
datestamp: 1721317388

View File

@@ -0,0 +1,61 @@
langcode: en
status: true
dependencies:
module:
- datetime
- log
- options
- user
id: log_test_view
label: 'Log test view'
module: views
description: ''
tag: ''
base_table: log_field_data
base_field: id
display:
default:
display_options:
defaults:
fields: false
pager: false
sorts: false
row:
type: fields
fields:
id:
id: id
table: log_field_data
field: id
relationship: none
entity_type: log
entity_field: id
plugin_id: field
name:
id: name
table: log_field_data
field: name
relationship: none
entity_type: log
entity_field: name
plugin_id: field
sorts:
timestamp:
id: timestamp
table: log_field_data
field: timestamp
relationship: none
group_type: group
admin_label: ''
order: DESC
exposed: false
expose:
label: ''
granularity: second
entity_type: log
entity_field: timestamp
plugin_id: log_standard
display_plugin: default
display_title: Master
id: default
position: 0

View File

@@ -0,0 +1,306 @@
<?php
namespace Drupal\Tests\log\Functional;
use Drupal\log\Entity\LogInterface;
/**
* Tests the Log form actions.
*
* @group Log
*/
class LogActionsTest extends LogTestBase {
/**
* Tests cloning a single log.
*/
public function testCloneSingleLog() {
// Create new user.
$original_user = $this->createUser([], 'Original user');
$this->assertNotEquals($this->loggedInUser->id(), $original_user->id());
// Create log.
$timestamp = \Drupal::time()->getRequestTime();
$log = $this->createLogEntity([
'uid' => $original_user->id(),
'name' => $this->randomMachineName(),
'created' => \Drupal::time()->getRequestTime(),
'done' => TRUE,
'timestamp' => $timestamp,
]);
$log->save();
$num_of_logs = $this->storage->getQuery()->count()->accessCheck(TRUE)->execute();
$this->assertEquals(1, $num_of_logs, 'There is one log in the system.');
$edit = [];
$edit['action'] = 'log_clone_action';
$edit['log_bulk_form[0]'] = TRUE;
$this->drupalGet('admin/content/log');
$this->submitForm($edit, $this->t('Apply to selected items'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains($this->t('Are you sure you want to clone this log?'));
$this->assertSession()->pageTextContains($this->t('New date'));
$new_timestamp = strtotime(date('Y-n-j', strtotime('+1 day', $timestamp)));
$edit_clone = [];
$edit_clone['date[date]'] = date('Y-m-d', $new_timestamp);
$this->submitForm($edit_clone, $this->t('Clone'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->addressEquals('admin/content/log');
$this->assertSession()->pageTextContains($this->t('Cloned 1 log'));
/** @var \Drupal\log\Entity\LogInterface[] $logs */
$logs = $this->storage->loadMultiple();
$this->assertEquals(2, count($logs), 'There are two logs in the system.');
$this->assertEquals($this->loggedInUser->id(), $logs[2]->getOwnerId(), 'Owner on the new log has been updated.');
$this->assertEquals($new_timestamp, $logs[2]->get('timestamp')->value, 'Timestamp on the new log has been updated.');
}
/**
* Tests cloning multiple logs.
*/
public function testCloneMultipleLogs() {
// Create new user.
$original_user = $this->createUser([], 'Original user');
$this->assertNotEquals($this->loggedInUser->id(), $original_user->id());
// Create logs.
$timestamp = \Drupal::time()->getRequestTime();
for ($i = 0; $i < 3; $i++) {
$log = $this->createLogEntity([
'uid' => $original_user->id(),
'name' => $this->randomMachineName(),
'created' => \Drupal::time()->getRequestTime(),
'done' => TRUE,
'timestamp' => $timestamp,
]);
$log->save();
}
$num_of_logs = $this->storage->getQuery()->count()->accessCheck(TRUE)->execute();
$this->assertEquals(3, $num_of_logs, 'There are three logs in the system.');
$edit = [];
$edit['action'] = 'log_clone_action';
for ($i = 0; $i < 3; $i++) {
$edit['log_bulk_form[' . $i . ']'] = TRUE;
}
$this->drupalGet('admin/content/log');
$this->submitForm($edit, $this->t('Apply to selected items'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains($this->t('Are you sure you want to clone these logs?'));
$this->assertSession()->pageTextContains($this->t('New date'));
$new_timestamp = strtotime(date('Y-n-j', strtotime('+1 day', $timestamp)));
$edit_clone = [];
$edit_clone['date[date]'] = date('Y-m-d', $new_timestamp);
$this->submitForm($edit_clone, $this->t('Clone'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->addressEquals('admin/content/log');
$this->assertSession()->pageTextContains($this->t('Cloned 3 logs'));
$logs = $this->storage->loadMultiple();
$this->assertEquals(6, count($logs), 'There are six logs in the system.');
for ($i = 1; $i <= 3; $i++) {
$this->assertEquals($this->loggedInUser->id(), $logs[3 + $i]->getOwnerId(), 'Owner on the new log has been updated');
$this->assertEquals($new_timestamp, $logs[3 + $i]->get('timestamp')->value, 'Timestamp on the new log has been updated.');
}
}
/**
* Tests rescheduling a single log to an absolute date.
*/
public function testRescheduleSingleLogAbsolute() {
$timestamp = \Drupal::time()->getRequestTime();
$log = $this->createLogEntity([
'name' => $this->randomMachineName(),
'created' => \Drupal::time()->getRequestTime(),
'done' => TRUE,
'timestamp' => $timestamp,
]);
$log->save();
$num_of_logs = $this->storage->getQuery()->count()->accessCheck(TRUE)->execute();
$this->assertEquals(1, $num_of_logs, 'There is one log in the system.');
$edit = [];
$edit['action'] = 'log_reschedule_action';
$edit['log_bulk_form[0]'] = TRUE;
$this->drupalGet('admin/content/log');
$this->submitForm($edit, $this->t('Apply to selected items'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains($this->t('Are you sure you want to reschedule this log?'));
$this->assertSession()->pageTextContains($this->t('New date'));
$new_timestamp = strtotime(date('Y-n-j', strtotime('+1 day', $timestamp)));
$edit_reschedule = [];
$edit_reschedule['date[date]'] = date('Y-m-d', $new_timestamp);
$this->submitForm($edit_reschedule, $this->t('Reschedule'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->addressEquals('admin/content/log');
$this->assertSession()->pageTextContains($this->t('Rescheduled 1 log'));
$logs = $this->storage->loadMultiple();
$this->assertEquals(1, $num_of_logs, 'There is one log in the system.');
$log = reset($logs);
$this->assertEquals($new_timestamp, $log->get('timestamp')->value, 'Timestamp on the log has changed.');
$this->assertEquals('pending', $log->get('status')->value, 'Log has been set to pending.');
}
/**
* Tests rescheduling multiple logs to an absolute date.
*/
public function testRescheduleMultipleLogsAbsolute() {
$timestamp = \Drupal::time()->getRequestTime();
for ($i = 0; $i < 3; $i++) {
$timestamp = strtotime(date('Y-n-j', strtotime('+1 day', $timestamp)));
$log = $this->createLogEntity([
'name' => $this->randomMachineName(),
'created' => \Drupal::time()->getRequestTime(),
'done' => TRUE,
'timestamp' => $timestamp,
]);
$log->save();
}
$num_of_logs = $this->storage->getQuery()->count()->accessCheck(TRUE)->execute();
$this->assertEquals(3, $num_of_logs, 'There are three logs in the system.');
$edit = [];
$edit['action'] = 'log_reschedule_action';
for ($i = 0; $i < 3; $i++) {
$edit['log_bulk_form[' . $i . ']'] = TRUE;
}
$this->drupalGet('admin/content/log');
$this->submitForm($edit, $this->t('Apply to selected items'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains($this->t('Are you sure you want to reschedule these logs?'));
$this->assertSession()->pageTextContains($this->t('New date'));
$new_timestamp = strtotime('+1 day', $timestamp);
$edit_reschedule = [];
$edit_reschedule['date[date]'] = date('Y-m-d', $new_timestamp);
$this->submitForm($edit_reschedule, $this->t('Reschedule'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->addressEquals('admin/content/log');
$this->assertSession()->pageTextContains($this->t('Rescheduled 3 logs'));
$logs = $this->storage->loadMultiple();
$this->assertEquals(3, count($logs), 'There are three logs in the system.');
foreach ($logs as $log) {
$this->assertEquals($new_timestamp, $log->get('timestamp')->value, 'Timestamp on the log has changed.');
$this->assertEquals('pending', $log->get('status')->value, 'Log has been set to pending.');
}
}
/**
* Tests rescheduling a single log to an relative date.
*/
public function testRescheduleSingleLogRelative() {
$timestamp = \Drupal::time()->getRequestTime();
$log = $this->createLogEntity([
'name' => $this->randomMachineName(),
'created' => \Drupal::time()->getRequestTime(),
'done' => TRUE,
'timestamp' => $timestamp,
]);
$log->save();
$num_of_logs = $this->storage->getQuery()->count()->accessCheck(TRUE)->execute();
$this->assertEquals(1, $num_of_logs, 'There is one log in the system.');
$edit = [];
$edit['action'] = 'log_reschedule_action';
$edit['log_bulk_form[0]'] = TRUE;
$this->drupalGet('admin/content/log');
$this->submitForm($edit, $this->t('Apply to selected items'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains($this->t('Are you sure you want to reschedule this log?'));
$this->assertSession()->pageTextContains($this->t('New date'));
$edit_reschedule = [];
$edit_reschedule['type_of_date'] = 1;
$this->submitForm($edit_reschedule, $this->t('Reschedule'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->addressEquals('admin/content/log/reschedule');
$this->assertSession()->pageTextContains($this->t('Please enter the amount of time for rescheduling.'));
$new_timestamp = strtotime('+1 day', $timestamp);
$edit_reschedule = [];
$edit_reschedule['type_of_date'] = 1;
$edit_reschedule['amount'] = 1;
$edit_reschedule['time'] = 'day';
$this->submitForm($edit_reschedule, $this->t('Reschedule'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->addressEquals('admin/content/log');
$this->assertSession()->pageTextContains($this->t('Rescheduled 1 log'));
$logs = $this->storage->loadMultiple();
$this->assertEquals(1, $num_of_logs, 'There is one log in the system.');
$log = reset($logs);
$this->assertEquals($new_timestamp, $log->get('timestamp')->value, 'Timestamp on the log has changed.');
$this->assertEquals('pending', $log->get('status')->value, 'Log has been set to pending.');
}
/**
* Tests rescheduling multiple logs to an relative date.
*/
public function testRescheduleMultipleLogsRelative() {
$timestamp = \Drupal::time()->getRequestTime();
$expected_timestamps = [];
for ($i = 0; $i < 3; $i++) {
$timestamp = strtotime('+1 day', $timestamp);
$log = $this->createLogEntity([
'name' => $this->randomMachineName(),
'created' => \Drupal::time()->getRequestTime(),
'done' => TRUE,
'timestamp' => $timestamp,
]);
$log->save();
// Save the expected timestamp for the log.
$new_timestamp = strtotime('-1 month', $timestamp);
$expected_timestamps[$log->id()] = $new_timestamp;
}
$num_of_logs = $this->storage->getQuery()->count()->accessCheck(TRUE)->execute();
$this->assertEquals(3, $num_of_logs, 'There are three logs in the system.');
$edit = [];
$edit['action'] = 'log_reschedule_action';
for ($i = 0; $i < 3; $i++) {
$edit['log_bulk_form[' . $i . ']'] = TRUE;
}
$this->drupalGet('admin/content/log');
$this->submitForm($edit, $this->t('Apply to selected items'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains($this->t('Are you sure you want to reschedule these logs?'));
$this->assertSession()->pageTextContains($this->t('New date'));
$edit_reschedule = [];
$edit_reschedule['type_of_date'] = 1;
$edit_reschedule['amount'] = -1;
$edit_reschedule['time'] = 'month';
$this->submitForm($edit_reschedule, $this->t('Reschedule'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->addressEquals('admin/content/log');
$this->assertSession()->pageTextContains($this->t('Rescheduled 3 logs'));
$logs = $this->storage->loadMultiple();
$this->assertEquals(3, count($logs), 'There are three logs in the system.');
$log_timestamps = array_map(function (LogInterface $log) {
return $log->get('timestamp')->value;
}, $logs);
$this->assertEquals($expected_timestamps, $log_timestamps, 'Logs have been rescheduled');
}
}

View File

@@ -0,0 +1,113 @@
<?php
namespace Drupal\Tests\log\Functional;
use Drupal\Core\StringTranslation\StringTranslationTrait;
/**
* Tests the Log CRUD.
*
* @group Log
*/
class LogCRUDTest extends LogTestBase {
use StringTranslationTrait;
/**
* Fields are displayed correctly.
*/
public function testFieldsVisibility() {
$this->drupalGet('log/add/default');
$this->assertSession()->statusCodeEquals('200');
$assert_session = $this->assertSession();
$assert_session->fieldExists('name[0][value]');
$assert_session->fieldExists('timestamp[0][value][date]');
$assert_session->fieldExists('timestamp[0][value][time]');
$assert_session->fieldExists('status');
$assert_session->fieldExists('revision_log_message[0][value]');
$assert_session->fieldExists('uid[0][target_id]');
$assert_session->fieldExists('created[0][value][date]');
$assert_session->fieldExists('created[0][value][time]');
}
/**
* Create Log entity.
*/
public function testCreateLog() {
$assert_session = $this->assertSession();
$name = $this->randomMachineName();
$edit = [
'name[0][value]' => $name,
];
$this->drupalGet('log/add/default');
$this->submitForm($edit, $this->t('Save'));
$result = $this->storage
->getQuery()
->range(0, 1)
->accessCheck(TRUE)
->execute();
$log_id = reset($result);
$log = $this->storage->load($log_id);
$this->assertEquals($log->get('name')->value, $name, 'Log has been saved.');
$assert_session->pageTextContains("Saved log: $name");
$assert_session->pageTextContains($name);
}
/**
* Display log entity.
*/
public function testViewLog() {
$edit = [
'name' => $this->randomMachineName(),
'created' => \Drupal::time()->getRequestTime(),
'done' => TRUE,
];
$log = $this->createLogEntity($edit);
$log->save();
$this->drupalGet($log->toUrl('canonical'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains($edit['name']);
$this->assertSession()->responseContains(\Drupal::service('date.formatter')->format(\Drupal::time()->getRequestTime()));
}
/**
* Edit log entity.
*/
public function testEditLog() {
$log = $this->createLogEntity();
$log->save();
$edit = [
'name[0][value]' => $this->randomMachineName(),
];
$this->drupalGet($log->toUrl('edit-form'));
$this->submitForm($edit, $this->t('Save'));
$this->assertSession()->pageTextContains($edit['name[0][value]']);
}
/**
* Delete log entity.
*/
public function testDeleteLog() {
$log = $this->createLogEntity();
$log->save();
$label = $log->getName();
$log_id = $log->id();
$this->drupalGet($log->toUrl('delete-form'));
$this->submitForm([], $this->t('Delete'));
$this->assertSession()->responseContains($this->t('The @entity-type %label has been deleted.', [
'@entity-type' => $log->getEntityType()->getSingularLabel(),
'%label' => $label,
]));
$this->assertNull($this->storage->load($log_id));
}
}

View File

@@ -0,0 +1,100 @@
<?php
namespace Drupal\Tests\log\Functional;
use Drupal\Core\StringTranslation\StringTranslationTrait;
/**
* Tests the Log name pattern.
*
* @group Log
*/
class LogNamePatternTest extends LogTestBase {
use StringTranslationTrait;
/**
* Tests creating a log entity without name.
*/
public function testCreateLogWithoutName() {
$edit = [
'status' => 'done',
];
$this->drupalGet('log/add/name_pattern');
$this->submitForm($edit, $this->t('Save'));
$result = $this->storage
->getQuery()
->range(0, 1)
->accessCheck(TRUE)
->execute();
$log_id = reset($result);
$log = $this->storage->load($log_id);
$this->assertEquals($log->label(), $log_id . ' done', 'Log name is the pattern and not the name.');
$this->drupalGet($log->toUrl('canonical'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains($log_id);
}
/**
* Tests creating a log entity with name.
*/
public function testCreateLogWithName() {
$name = $this->randomMachineName();
$edit = [
'name[0][value]' => $name,
];
$this->drupalGet('log/add/name_pattern');
$this->submitForm($edit, $this->t('Save'));
$result = $this->storage
->getQuery()
->range(0, 1)
->accessCheck(TRUE)
->execute();
$log_id = reset($result);
$log = $this->storage->load($log_id);
$this->assertEquals($log->get('name')->value, $name, 'Log name is the pattern and not the name.');
$this->drupalGet($log->toUrl('canonical'));
$this->assertSession()->statusCodeEquals(200);
$this->assertSession()->pageTextContains($name);
}
/**
* Edit log entity.
*/
public function testEditLog() {
$log = $this->createLogEntity(['type' => 'name_pattern']);
$log->save();
// Test that a manually set name does not get overwritten.
$edit = [
'name[0][value]' => $this->randomMachineName(),
];
$this->drupalGet($log->toUrl('edit-form'));
$this->submitForm($edit, $this->t('Save'));
$this->assertSession()->pageTextContains($edit['name[0][value]']);
// Test that clearing the name forces it to be auto-generated.
$edit = [
'name[0][value]' => '',
'status' => 'pending',
];
$this->drupalGet($log->toUrl('edit-form'));
$this->submitForm($edit, $this->t('Save'));
$this->assertSession()->pageTextContains($log->id() . ' pending');
// Test that updating a log with an auto-generated name automatically
// updates the name.
$edit = [
'status' => 'done',
];
$this->drupalGet($log->toUrl('edit-form'));
$this->submitForm($edit, $this->t('Save'));
$this->assertSession()->pageTextContains($log->id() . ' done');
}
}

View File

@@ -0,0 +1,99 @@
<?php
namespace Drupal\Tests\log\Functional;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Tests\BrowserTestBase;
/**
* Tests the Log CRUD.
*/
abstract class LogTestBase extends BrowserTestBase {
use StringTranslationTrait;
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* The log storage handler.
*
* @var \Drupal\group\Entity\Storage\GroupRoleStorageInterface
*/
protected $storage;
/**
* Modules to install.
*
* @var array
*/
protected static $modules = [
'entity',
'user',
'log',
'log_test',
'field',
'text',
];
/**
* A test user with administrative privileges.
*
* @var \Drupal\user\UserInterface
*/
protected $adminUser;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
/** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
$entity_type_manager = $this->container->get('entity_type.manager');
$this->storage = $entity_type_manager->getStorage('log');
$this->adminUser = $this->drupalCreateUser($this->getAdministratorPermissions());
$this->drupalLogin($this->adminUser);
drupal_flush_all_caches();
}
/**
* Gets the permissions for the admin user.
*
* @return string[]
* The permissions.
*/
protected function getAdministratorPermissions() {
return [
'access administration pages',
'administer log',
'view any log',
'create default log',
'view any default log',
'update own default log',
'update any default log',
'delete own default log',
'delete any default log',
];
}
/**
* Creates a log entity.
*
* @param array $values
* Array of values to feed the entity.
*
* @return \Drupal\log\Entity\LogInterface
* The log entity.
*/
protected function createLogEntity(array $values = []) {
$entity = $this->storage->create($values + [
'name' => $this->randomMachineName(),
'created' => \Drupal::time()->getRequestTime(),
'type' => 'default',
]);
return $entity;
}
}

View File

@@ -0,0 +1,100 @@
<?php
namespace Drupal\Tests\log\Kernel;
use Drupal\Core\Action\ActionInterface;
use Drupal\KernelTests\KernelTestBase;
use Drupal\Tests\log\Traits\LogCreationTrait;
/**
* Tests for log actions.
*
* @group Log
*/
class LogActionsTest extends KernelTestBase {
use LogCreationTrait;
/**
* {@inheritdoc}
*/
protected static $modules = [
'system',
'user',
'log',
'log_test',
'datetime',
'state_machine',
];
/**
* The action manager.
*
* @var \Drupal\Core\Action\ActionManager
*/
protected $actionManager;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->actionManager = $this->container->get('plugin.manager.action');
$this->installEntitySchema('user');
$this->installEntitySchema('log');
$this->installSchema('system', ['sequences']);
$this->installConfig(['log', 'log_test']);
}
/**
* Tests that all the custom actions are available for the log entity type.
*/
public function testAvailableActions() {
$definitions = $this->actionManager->getDefinitionsByType('log');
$expected_actions = [
'log_mark_as_done_action',
'log_mark_as_pending_action',
'log_clone_action',
'log_reschedule_action',
];
foreach ($expected_actions as $expected_action) {
$this->assertTrue(in_array($expected_action, array_keys($definitions)));
}
}
/**
* Tests that the mark as done action sets the right state.
*/
public function testMarkAsDoneAction() {
$action = $this->actionManager->createInstance('log_mark_as_done_action');
$this->assertTrue($action instanceof ActionInterface, 'The action implements the correct interface.');
$new_log = $this->createLogEntity([
'name' => $this->randomMachineName(),
'status' => 'pending',
]);
$new_log->save();
$action->execute($new_log);
$storage = $this->container->get('entity_type.manager')->getStorage('log');
$log = $storage->load($new_log->id());
$this->assertEquals('done', $log->get('status')->value);
}
/**
* Tests that the mark as pending action sets the right state.
*/
public function testMarkAsPendingAction() {
$action = $this->actionManager->createInstance('log_mark_as_pending_action');
$this->assertTrue($action instanceof ActionInterface, 'The action implements the correct interface.');
$new_log = $this->createLogEntity([
'name' => $this->randomMachineName(),
'status' => 'done',
]);
$new_log->save();
$action->execute($new_log);
$storage = $this->container->get('entity_type.manager')->getStorage('log');
$log = $storage->load($new_log->id());
$this->assertEquals('pending', $log->get('status')->value);
}
}

View File

@@ -0,0 +1,203 @@
<?php
namespace Drupal\Tests\log\Kernel;
use Drupal\Component\Serialization\Json;
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
use Drupal\Tests\log\Traits\LogCreationTrait;
use Symfony\Component\HttpFoundation\Request;
/**
* Tests name autocomplete for logs.
*
* @group Log
*/
class NameAutocompleteTest extends EntityKernelTestBase {
use LogCreationTrait;
/**
* {@inheritdoc}
*/
protected static $modules = [
'log',
'log_test',
'datetime',
'entity',
'state_machine',
];
/**
* An admin account.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $adminAccount;
/**
* An account with 'view any default log' permission.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $anyAccount;
/**
* An account with 'view own default log' permission.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $ownAccount;
/**
* An account with no view permissions.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $noneAccount;
/**
* A collection of logs.
*
* @var \Drupal\log\Entity\LogInterface[]
*/
protected $logs = [];
/**
* The request stack used for testing.
*
* @var \Symfony\Component\HttpFoundation\RequestStack
*/
protected $requestStack;
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->installEntitySchema('log');
$this->installConfig(['log', 'log_test']);
// Create the test user accounts.
$this->adminAccount = $this->createUser([], ['administer log']);
$this->anyAccount = $this->createUser([], [
'view any default log',
'create default log',
]);
$this->ownAccount = $this->createUser([], [
'view own default log',
'create default log',
]);
$this->noneAccount = $this->createUser([], ['create default log']);
// Create the different log entries.
$this->logs[] = $this->createLogEntity([
'name' => 'First log',
'uid' => $this->adminAccount->id(),
]);
$this->logs[] = $this->createLogEntity([
'name' => 'Second log',
'uid' => $this->adminAccount->id(),
]);
$this->logs[] = $this->createLogEntity([
'name' => 'Third log',
'uid' => $this->ownAccount->id(),
]);
}
/**
* Returns the result of an autocomplete request.
*
* @param string $input
* The label of the entity to query by.
*
* @return mixed
* The JSON value encoded in its appropriate PHP type.
*
* @throws \Exception
*/
protected function getAutocompleteResult($input) {
// Rebuild the route cache on each request to avoid parameter bag cache
// leaks.
$this->container->get('router.builder')->rebuild();
// Build the autocomplete request, 'q' is the right parameter to mock this.
$request = Request::create('/log/default/autocomplete');
$request->query->set('q', $input);
/** @var \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel */
$http_kernel = $this->container->get('http_kernel');
$response = $http_kernel->handle($request);
// The response is a JsonResponse and the content is a string that needs to
// be decoded to array.
$result = $response->getContent();
return Json::decode($result);
}
/**
* Tests name autocomplete route.
*/
public function testLogNameAutocomplete() {
// Tests admin account with an autocomplete query that shouldn't return any
// logs.
$this->container->get('current_user')->setAccount($this->adminAccount);
$result = $this->getAutocompleteResult('nonsense');
$this->assertEmpty($result, 'No results for non matching search query.');
// Tests admin account so it returns the complete set of logs.
$result = $this->getAutocompleteResult('log');
$this->assertEquals(count($this->logs), count($result), 'Number of results for matching query and admin user is as expected.');
// With an account that has 'view any default log' permission, the result
// should be the complete set of logs.
$this->container->get('current_user')->setAccount($this->anyAccount);
$result = $this->getAutocompleteResult('log');
$this->assertEquals(3, count($result), 'Number of results for matching query and user with view any permission is as expected.');
// With an account that has 'view own default log' permission, the result
// should be the logs belonging to that user.
$this->container->get('current_user')->setAccount($this->ownAccount);
$result = $this->getAutocompleteResult('log');
$this->assertEquals(1, count($result), 'Number of results for matching query and user with view own permission is as expected.');
$own_log = array_filter($this->logs, function ($log) {
/** @var \Drupal\log\Entity\LogInterface $log */
return $log->id() == $this->ownAccount->id();
});
$own_log = reset($own_log);
$this->assertEquals($result[0], $own_log->label(), 'The right log for the user is returned.');
// With an account with no permissions and the right query, there should be
// no results anyway.
$this->container->get('current_user')->setAccount($this->noneAccount);
$result = $this->getAutocompleteResult('log');
$this->assertEmpty($result, 'No results for user without permissions.');
}
/**
* Tests the order of logs returned.
*/
public function testLogNameAutocompleteMultipleLogs() {
// Add a duplicate log that should be on top of the results.
$this->logs[] = $this->createLogEntity([
'name' => 'Z log',
'uid' => $this->adminAccount->id(),
]);
$this->logs[] = $this->createLogEntity([
'name' => 'Z log',
'uid' => $this->adminAccount->id(),
]);
$this->container->get('current_user')->setAccount($this->adminAccount);
$result = $this->getAutocompleteResult('log');
$this->assertEquals(count($this->logs) - 1, count($result), 'Duplicated log is not duplicated in the autocomplete results.');
$expected_order = [
'Z log',
'First log',
'Second log',
'Third log',
];
$this->assertEquals($expected_order, $result, 'Order of results is as expected.');
}
}

View File

@@ -0,0 +1,146 @@
<?php
namespace Drupal\Tests\log\Kernel;
use Drupal\Tests\log\Traits\LogCreationTrait;
use Drupal\Tests\views\Kernel\ViewsKernelTestBase;
use Drupal\views\Tests\ViewTestData;
use Drupal\views\Views;
/**
* Tests for Drupal\log\Plugin\views\sort\LogTimestampIdSort handler.
*
* @group Log
*/
class SortTimestampIdTest extends ViewsKernelTestBase {
use LogCreationTrait;
/**
* {@inheritdoc}
*/
protected static $modules = ['log', 'log_test', 'datetime', 'state_machine'];
/**
* Views used by this test.
*
* @var array
*/
public static $testViews = ['log_test_view'];
/**
* ASC expected result.
*
* @var array
*/
protected $expectedResultASC = [];
/**
* DESC expected result.
*
* @var array
*/
protected $expectedResultDESC = [];
/**
* {@inheritdoc}
*/
protected function setUp($import_test_views = TRUE): void {
parent::setUp();
$this->installEntitySchema('log');
$this->installConfig(['log', 'log_test']);
ViewTestData::createTestViews(get_class($this), ['log_test']);
// Establish two different timestamps so the sort is meaningful.
$first_timestamp = 376185600;
$second_timestamp = 386121600;
// Three entities is the minimum amount to test two with the same timestamp
// and different ID and one with unique timestamp.
$first_entity = $this->createLogEntity([
'name' => 'First',
'timestamp' => $first_timestamp,
]);
$second_entity = $this->createLogEntity([
'name' => 'Second',
'timestamp' => $first_timestamp,
]);
$third_entity = $this->createLogEntity([
'name' => 'Third',
'timestamp' => $second_timestamp,
]);
// Fill the expected results for the combinations.
$this->expectedResultASC = [
['name' => $first_entity->get('name')->value, 'id' => $first_entity->id()],
['name' => $second_entity->get('name')->value, 'id' => $second_entity->id()],
['name' => $third_entity->get('name')->value, 'id' => $third_entity->id()],
];
$this->expectedResultDESC = [
['name' => $third_entity->get('name')->value, 'id' => $third_entity->id()],
['name' => $second_entity->get('name')->value, 'id' => $second_entity->id()],
['name' => $first_entity->get('name')->value, 'id' => $first_entity->id()],
];
}
/**
* Tests the sorting: Timestamp /ID ASC.
*/
public function testLogTimestampIdAscSort() {
$view = Views::getView('log_test_view');
$view->setDisplay();
$view->displayHandlers->get('default')->overrideOption('sorts', [
'timestamp' => [
'id' => 'timestamp',
'table' => 'log_field_data',
'field' => 'timestamp',
'relationship' => 'none',
'order' => 'ASC',
'plugin_id' => 'log_standard',
],
]);
$this->executeView($view);
$this->assertEquals(3, count($view->result), 'The number of returned rows match.');
$this->assertIdenticalResultset($view, $this->expectedResultASC, [
'name' => 'name',
'id' => 'id',
], 'ASC sort displays as expected');
$view->destroy();
unset($view);
}
/**
* Tests the sorting: Timestamp/ID DESC.
*/
public function testLogTimestampIdDescSort() {
$view = Views::getView('log_test_view');
$view->setDisplay();
$view->displayHandlers->get('default')->overrideOption('sorts', [
'timestamp' => [
'id' => 'timestamp',
'table' => 'log_field_data',
'field' => 'timestamp',
'relationship' => 'none',
'order' => 'DESC',
'plugin_id' => 'log_standard',
],
]);
$this->executeView($view);
$this->assertEquals(3, count($view->result), 'The number of returned rows match.');
$this->assertIdenticalResultset($view, $this->expectedResultDESC, [
'name' => 'name',
'id' => 'id',
], 'DESC sort displays as expected');
$view->destroy();
unset($view);
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace Drupal\Tests\log\Traits;
use Drupal\log\Entity\Log;
/**
* Provides methods to create log entities.
*
* This trait is meant to be used only by test classes.
*/
trait LogCreationTrait {
/**
* Creates a log entity.
*
* @param array $values
* Array of values to feed the entity.
*
* @return \Drupal\log\Entity\LogInterface
* The log entity.
*
* @throws \Drupal\Core\Entity\EntityStorageException
*/
protected function createLogEntity(array $values = []) {
/** @var \Drupal\log\Entity\LogInterface $entity */
$entity = Log::create($values + [
'name' => $this->randomMachineName(),
'type' => 'default',
]);
$entity->save();
return $entity;
}
}