Skip to content
Snippets Groups Projects
Commit 820d5b2c authored by Alexey Korepov's avatar Alexey Korepov
Browse files

Issue #3336601 by Murz: Add a stub for date.formatter service

parent 4504a524
No related branches found
Tags 7.x-2.0-beta1
No related merge requests found
......@@ -13,11 +13,13 @@ class TestHelpersExampleController extends ControllerBase {
* Renders a list of two articles, reverse sorted by title.
*/
public function articlesList() {
$amount = \Drupal::config('my_site')->get('articles_to_display');
$articlesIds = \Drupal::entityQuery('node')
->condition('status', 1)
->condition('type', 'article')
->sort('title', 'DESC')
->range(0, 2)
->sort('created', 'DESC')
->range(0, $amount)
->execute();
$articles = \Drupal::entityTypeManager()
......@@ -26,7 +28,7 @@ class TestHelpersExampleController extends ControllerBase {
$articlesList = [];
foreach ($articles as $article) {
$linkText = $article->label() . ' (' . $article->id() . ')';
$linkText = $article->label() . ' (' . \Drupal::service('date.formatter')->format($article->created->value) . ')';
$articlesList[] = $article->toLink($linkText);
}
......
......@@ -2,10 +2,14 @@
namespace src\Unit;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ImmutableConfig;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\Query\QueryInterface;
use Drupal\Core\Field\FieldItemList;
use Drupal\Core\Link;
use Drupal\node\NodeInterface;
use Drupal\Tests\UnitTestCase;
......@@ -27,7 +31,7 @@ class TestHelpersExampleControllerClassicTest extends UnitTestCase {
$entityQuery->method('sort')
->willReturnCallback(
function ($field, $direction = 'ASC', $langcode = NULL) use ($entityQuery) {
$this->assertEquals('title', $field);
$this->assertEquals('created', $field);
$this->assertEquals('DESC', $direction);
return $entityQuery;
}
......@@ -78,11 +82,15 @@ class TestHelpersExampleControllerClassicTest extends UnitTestCase {
$node1 = $this->createMock(NodeInterface::class);
$node1->method('id')->willReturn('1');
$node1->method('label')->willReturn('Article 1');
$node1->created = $this->createPartialMock(FieldItemList::class, ['__get']);
$node1->created->method('__get')->with('value')->willReturn('1672574400');
$node1->method('toLink')->willReturnCallback($toLinkMock);
$node2 = $this->createMock(NodeInterface::class);
$node2->method('id')->willReturn('2');
$node2->method('label')->willReturn('Article 2');
$node2->created = $this->createPartialMock(FieldItemList::class, ['__get']);
$node2->created->method('__get')->with('value')->willReturn('1672660800');
$node2->method('toLink')->willReturnCallback($toLinkMock);
$entityStorage = $this->createMock(EntityStorageInterface::class);
......@@ -92,15 +100,25 @@ class TestHelpersExampleControllerClassicTest extends UnitTestCase {
$entityTypeManager = $this->createMock(EntityTypeManagerInterface::class);
$entityTypeManager->method('getStorage')->willReturn($entityStorage);
$dateFormatter = $this->createMock(DateFormatterInterface::class);
$dateFormatter->method('format')->willReturn($this->returnArgument(0));
$configFactory = $this->createMock(ConfigFactoryInterface::class);
$config = $this->createMock(ImmutableConfig::class);
$config->method('get')->willReturn(2);
$configFactory->method('get')->willReturn($config);
$container = new ContainerBuilder();
$container->set('entity_type.manager', $entityTypeManager);
$container->set('date.formatter', $dateFormatter);
$container->set('config.factory', $configFactory);
\Drupal::setContainer($container);
$controller = new TestHelpersExampleController();
$result = $controller->articlesList();
$this->assertEquals('Article 1 (1)', $result['#items'][0]->getText());
$this->assertEquals('Article 2 (2)', $result['#items'][1]->getText());
$this->assertEquals('Article 1 (1672574400)', $result['#items'][0]->getText());
$this->assertEquals('Article 2 (1672660800)', $result['#items'][1]->getText());
}
}
......@@ -20,22 +20,24 @@ class TestHelpersExampleControllerModernConditionsTest extends UnitTestCase {
* @covers ::articlesList
*/
public function testArticlesList() {
UnitTestHelpers::createEntityStub(Node::class, ['title' => 'Article 1'])->save();
UnitTestHelpers::createEntityStub(Node::class, ['title' => 'Article 2'])->save();
UnitTestHelpers::service('config.factory')->stubSetConfig('my_site', ['articles_to_display' => 2]);
UnitTestHelpers::service('date.formatter')->stubSetFormat('medium', 'Medium', 'd.m.Y');
UnitTestHelpers::saveEntityStub(Node::class, ['title' => 'Article 1', 'created' => '1672574400']);
UnitTestHelpers::saveEntityStub(Node::class, ['title' => 'Article 2', 'created' => '1672660800']);
UnitTestHelpers::getServiceStub('entity.query.sql')->stubSetExecuteHandler(function () {
UnitTestCaseWrapper::assertTrue(UnitTestHelpers::queryIsSubsetOf($this, \Drupal::entityQuery('node')
->condition('status', 1)
->condition('type', 'article')
->sort('title', 'DESC')
->sort('created', 'DESC')
->range(0, 2)));
return ['1', '2'];
});
$result = (new TestHelpersExampleController())->articlesList();
$this->assertEquals('Article 1 (1)', $result['#items'][0]->getText());
$this->assertEquals('Article 2 (2)', $result['#items'][1]->getText());
$this->assertEquals('Article 1 (01.01.2023)', $result['#items'][0]->getText());
$this->assertEquals('Article 2 (02.01.2023)', $result['#items'][1]->getText());
}
}
......@@ -19,17 +19,17 @@ class TestHelpersExampleControllerModernResultTest extends UnitTestCase {
* @covers ::articlesList
*/
public function testArticlesList() {
UnitTestHelpers::createEntityStub(Node::class, ['type' => 'article', 'title' => 'Article 1', 'status' => '1'])->save();
UnitTestHelpers::createEntityStub(Node::class, ['type' => 'article', 'title' => 'Article 2', 'status' => '1'])->save();
UnitTestHelpers::createEntityStub(Node::class, ['type' => 'page', 'title' => 'Page 1', 'status' => '0'])->save();
UnitTestHelpers::createEntityStub(Node::class, ['type' => 'article', 'title' => 'Article 3', 'status' => '0'])->save();
UnitTestHelpers::createEntityStub(Node::class, ['type' => 'article', 'title' => 'Article 4', 'status' => '1'])->save();
UnitTestHelpers::service('config.factory')->stubSetConfig('my_site', ['articles_to_display' => 1]);
UnitTestHelpers::service('date.formatter')->stubSetFormat('medium', 'Medium', 'd.m.Y');
UnitTestHelpers::saveEntityStub(Node::class, ['type' => 'article', 'title' => 'Article 1', 'status' => '1', 'created' => '1672574400']);
UnitTestHelpers::saveEntityStub(Node::class, ['type' => 'article', 'title' => 'Article 2', 'status' => '1', 'created' => '1672660800']);
UnitTestHelpers::saveEntityStub(Node::class, ['type' => 'page', 'title' => 'Page 1', 'status' => '0', 'created' => '1672747200']);
UnitTestHelpers::saveEntityStub(Node::class, ['type' => 'article', 'title' => 'Article 3', 'status' => '0', 'created' => '1672833600']);
$result = (new TestHelpersExampleController())->articlesList();
$this->assertCount(2, $result['#items']);
$this->assertEquals('Article 4 (5)', $result['#items'][0]->getText());
$this->assertEquals('Article 2 (2)', $result['#items'][1]->getText());
$this->assertCount(1, $result['#items']);
$this->assertEquals('Article 2 (02.01.2023)', $result['#items'][0]->getText());
}
}
......@@ -12,7 +12,7 @@ use Drupal\test_helpers\UnitTestHelpers;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* A stub of the Drupal's default LanguageManager class.
* A stub of the Drupal's default ConfigFactory class.
*/
class ConfigFactoryStub extends ConfigFactory {
......
<?php
namespace Drupal\test_helpers\Stub;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Datetime\DateFormatter;
use Drupal\Core\Datetime\Entity\DateFormat;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\test_helpers\UnitTestHelpers;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* A stub of the Drupal's default DateFormatter class.
*/
class DateFormatterStub extends DateFormatter {
/**
* {@inheritdoc}
*/
public function __construct(
EntityTypeManagerInterface $entity_type_manager = NULL,
LanguageManagerInterface $language_manager = NULL,
TranslationInterface $translation = NULL,
ConfigFactoryInterface $config_factory = NULL,
RequestStack $request_stack = NULL
) {
$entity_type_manager ??= UnitTestHelpers::service('entity_type.manager');
$language_manager ??= UnitTestHelpers::service('language_manager');
$translation ??= UnitTestHelpers::service('string_translation');
$config_factory ??= UnitTestHelpers::service('config.factory');
$request_stack ??= UnitTestHelpers::service('request_stack');
// Creating default fallback format.
$entity_type_manager->stubGetOrCreateStorage(DateFormat::class);
$this->stubSetFormat('fallback', 'Fallback date format', 'D, m/d/Y - H:i', TRUE);
parent::__construct($entity_type_manager, $language_manager, $translation, $config_factory, $request_stack);
}
/**
* Sets the date format.
*/
public function stubSetFormat($name, $label, $pattern, $locked = 0) {
UnitTestHelpers::saveEntityStub(DateFormat::class, [
'id' => $name,
'label' => $label,
'pattern' => $pattern,
'locked' => $locked,
]);
}
}
......@@ -19,6 +19,13 @@ use Drupal\test_helpers\UnitTestHelpers;
*/
class EntityTypeManagerStub extends EntityTypeManager implements EntityTypeManagerStubInterface {
/**
* Static storage for initialized entity storages.
*
* @var array;
*/
protected $stubEntityStoragesByClass;
/**
* {@inheritdoc}
*/
......@@ -38,6 +45,8 @@ class EntityTypeManagerStub extends EntityTypeManager implements EntityTypeManag
$class_resolver ??= UnitTestHelpers::service('class_resolver');
$entity_last_installed_schema_repository ??= UnitTestHelpers::service('entity.last_installed_schema.repository');
$this->setContainer(UnitTestHelpers::getContainer());
// Calling original costructor with mocked services.
parent::__construct(
$namespaces,
......@@ -48,11 +57,13 @@ class EntityTypeManagerStub extends EntityTypeManager implements EntityTypeManag
$entity_last_installed_schema_repository
);
UnitTestHelpers::service('entity_type.manager', $this);
UnitTestHelpers::service('entity_type.repository', new EntityTypeRepository($this));
UnitTestHelpers::service('typed_data_manager', new TypedDataManagerStub());
UnitTestHelpers::setServices([
'entity_type.manager' => $this,
'entity_type.repository' => new EntityTypeRepository($this),
'entity_type.bundle.info' => NULL,
'entity.memory_cache' => NULL,
'entity_field.manager' => NULL,
'language_manager' => NULL,
'uuid' => NULL,
'entity.query.sql' => new EntityQueryServiceStub(),
......
......@@ -2,6 +2,7 @@
namespace Drupal\test_helpers\StubFactory;
use Drupal\Core\Cache\MemoryCache\MemoryCache;
use Drupal\Core\Entity\EntityInterface;
use Drupal\test_helpers\UnitTestHelpers;
......@@ -25,9 +26,28 @@ class EntityStorageStubFactory {
private function __construct() {
}
public static function create(string $entityTypeClass, $annotation = '\Drupal\Core\Entity\Annotation\ContentEntityType', array $options = []) {
public static function create(string $entityTypeClass, $annotation = NULL, array $options = []) {
switch ($annotation) {
case 'ContentEntityType':
case 'ConfigEntityType':
$annotation = '\Drupal\Core\Entity\Annotation\\' . $annotation;
}
$entityTypeDefinition = UnitTestHelpers::getPluginDefinition($entityTypeClass, 'Entity', $annotation);
if ($annotation) {
$entityTypeDefinition = UnitTestHelpers::getPluginDefinition($entityTypeClass, 'Entity', $annotation);
}
else {
$annotation = '\Drupal\Core\Entity\Annotation\ContentEntityType';
$entityTypeDefinition = UnitTestHelpers::getPluginDefinition($entityTypeClass, 'Entity', $annotation);
if ($entityTypeDefinition == NULL) {
$annotation = '\Drupal\Core\Entity\Annotation\ConfigEntityType';
$entityTypeDefinition = UnitTestHelpers::getPluginDefinition($entityTypeClass, 'Entity', $annotation);
}
}
if ($entityTypeDefinition == NULL) {
throw new \Exception("Can't parse annotation for class \$entityTypeClass using annotation $annotation");
}
$entityTypeStorage = $entityTypeDefinition->getStorageClass();
$staticStorage = &UnitTestHelpers::addService('test_helpers.static_storage')->get('test_helpers.entity_storage_stub.' . $entityTypeDefinition->id());
......@@ -39,21 +59,27 @@ class EntityStorageStubFactory {
$constructArguments = NULL;
if ($annotation == '\Drupal\Core\Entity\Annotation\ContentEntityType') {
$constructArguments = [
$entityTypeDefinition,
UnitTestHelpers::addService('database'),
UnitTestHelpers::addService('entity_field.manager'),
UnitTestHelpers::addService('cache.entity'),
UnitTestHelpers::addService('language_manager'),
UnitTestHelpers::addService('entity.memory_cache'),
UnitTestHelpers::addService('entity_type.bundle.info'),
UnitTestHelpers::addService('entity_type.manager'),
];
if ($options['constructorArguments'] ?? NULL) {
$constructArguments = $options['constructorArguments'];
}
elseif ($annotation == '\Drupal\Core\Entity\Annotation\ConfigEntityType') {
// Does nothing as for now.
// @todo Add list of required services.
switch ($annotation) {
case '\Drupal\Core\Entity\Annotation\ContentEntityType':
$configEntityType = FALSE;
$constructArguments ??= [
$entityTypeDefinition,
UnitTestHelpers::addService('database'),
UnitTestHelpers::addService('entity_field.manager'),
UnitTestHelpers::addService('cache.entity'),
UnitTestHelpers::addService('language_manager'),
UnitTestHelpers::addService('entity.memory_cache'),
UnitTestHelpers::addService('entity_type.bundle.info'),
UnitTestHelpers::addService('entity_type.manager'),
];
break;
case '\Drupal\Core\Entity\Annotation\ConfigEntityType':
$configEntityType = TRUE;
break;
}
$overridedMethods = [
......@@ -99,7 +125,7 @@ class EntityStorageStubFactory {
$this->memoryCache = UnitTestHelpers::addService('cache.backend.memory')->get('entity_storage_stub.memory_cache.' . $this->entityTypeId);
$this->cacheBackend = UnitTestHelpers::addService('cache.backend.memory')->get('entity_storage_stub.cache.' . $this->entityTypeId);
});
}, $entityStorage, 'stubInit');
$entityStorage->stubInit();
}
......
......@@ -7,6 +7,7 @@ use Drupal\Component\Transliteration\PhpTransliteration;
use Drupal\Component\Uuid\Php;
use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
use Drupal\Core\Cache\MemoryBackendFactory;
use Drupal\Core\Cache\MemoryCache\MemoryCache;
use Drupal\Core\Database\Query\ConditionInterface as DatabaseQueryConditionInterface;
use Drupal\Core\Database\Query\SelectInterface as DatabaseSelectInterface;
use Drupal\Core\DependencyInjection\ContainerBuilder;
......@@ -18,6 +19,7 @@ use Drupal\Core\Logger\LoggerChannelFactory;
use Drupal\test_helpers\lib\TestHelpersStaticStorageService;
use Drupal\test_helpers\Stub\ConfigFactoryStub;
use Drupal\test_helpers\Stub\DatabaseStub;
use Drupal\test_helpers\Stub\DateFormatterStub;
use Drupal\test_helpers\Stub\EntityTypeBundleInfoStub;
use Drupal\test_helpers\Stub\EntityTypeManagerStub;
use Drupal\test_helpers\Stub\LanguageManagerStub;
......@@ -33,8 +35,15 @@ use Symfony\Component\Yaml\Yaml;
// This trick is to prevent 'Undefined constant' warnings in code sniffers.
defined('DRUPAL_ROOT') || define('DRUPAL_ROOT', '');
// This constant is used in some entity definitions from core.
// These constants are used in some entity definitions from core.
// They're defined in system.module, so just re-define them here.
defined('DRUPAL_DISABLED') || define('DRUPAL_DISABLED', 0);
defined('DRUPAL_OPTIONAL') || define('DRUPAL_OPTIONAL', 1);
defined('DRUPAL_REQUIRED') || define('DRUPAL_REQUIRED', 2);
defined('REGIONS_VISIBLE') || define('REGIONS_VISIBLE', 'visible');
defined('REGIONS_ALL') || define('REGIONS_ALL', 'all');
/**
* Helper functions to simplify writing of Unit Tests.
*/
......@@ -53,8 +62,10 @@ class UnitTestHelpers {
'class_resolver' => [self::class, 'getClassResolverStub'],
'config.factory' => ConfigFactoryStub::class,
'database' => DatabaseStub::class,
'date.formatter' => DateFormatterStub::class,
'entity_type.bundle.info' => EntityTypeBundleInfoStub::class,
'entity_type.manager' => EntityTypeManagerStub::class,
'entity.memory_cache' => MemoryCache::class,
'language_manager' => LanguageManagerStub::class,
'logger.factory' => LoggerChannelFactory::class,
'module_handler' => ModuleHandlerStub::class,
......@@ -455,6 +466,9 @@ class UnitTestHelpers {
public static function createEntityStub(string $entityTypeClassName, array $values = [], array $options = []) {
switch ($options['entity_base_type'] ?? NULL) {
default:
$annotation = NULL;
break;
case 'ContentEntityType':
$annotation = '\Drupal\Core\Entity\Annotation\ContentEntityType';
break;
......
<?php
namespace Drupal\Tests\test_helpers\Unit\Stub;
use Drupal\test_helpers\Stub\ConfigFactoryStub;
use Drupal\test_helpers\Stub\DateFormatterStub;
use Drupal\test_helpers\UnitTestHelpers;
use Drupal\Tests\UnitTestCase;
/**
* Tests DateFormatterStub class.
*
* @coversDefaultClass \Drupal\test_helpers\Stub\DateFormatterStub
* @group test_helpers
*/
class DateFormatterStubTest extends UnitTestCase {
/**
* @covers ::__construct
* @covers ::stubSetFormat
*/
public function testStubSetFormat() {
$dateFormatterStub = new DateFormatterStub();
$this->assertEquals('Sat, 01/01/2000 - 23:00', $dateFormatterStub->format(946728000));
$dateFormatterStub->stubSetFormat('medium', 'Medium', 'c');
$this->assertEquals('2000-01-01T23:00:00+11:00', $dateFormatterStub->format(946728000, 'medium'));
$entity = \Drupal::service('entity_type.manager')->getStorage('date_format')->load('medium');
$this->assertEquals('Medium', $entity->label());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment