improvements-2.x-dev/modules/improvements_taxonomy/tests/src/Functional/ImprovementsTaxonomyTest.php
modules/improvements_taxonomy/tests/src/Functional/ImprovementsTaxonomyTest.php
<?php
namespace Drupal\Tests\improvements_taxonomy\Functional;
use Drupal\Core\Condition\ConditionInterface;
use Drupal\Core\Condition\ConditionManager;
use Drupal\Core\Routing\RouteMatch;
use Drupal\druhels\TaxonomyHelper;
use Drupal\improvements_taxonomy\Cache\ParentTermCacheContext;
use Drupal\pathauto\Entity\PathautoPattern;
use Drupal\taxonomy\Entity\Term;
use Drupal\taxonomy\Entity\Vocabulary;
use Drupal\taxonomy\VocabularyInterface;
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\improvements\Traits\ImprovementsTestTrait;
use Drupal\Tests\node\Traits\NodeCreationTrait;
use Drupal\Tests\taxonomy\Traits\TaxonomyTestTrait;
use Symfony\Component\Routing\Route;
class ImprovementsTaxonomyTest extends BrowserTestBase {
use ImprovementsTestTrait;
use NodeCreationTrait;
use TaxonomyTestTrait;
/**
* {@inheritDoc}
*/
protected $defaultTheme = 'stark';
/**
* {@inheritDoc}
*/
protected static $modules = ['improvements_taxonomy'];
protected VocabularyInterface $categoriesVocabulary;
/**
* {@inheritDoc}
*/
protected function setUp(): void {
parent::setUp();
// Create "page" node type
$this->createContentType(['type' => 'page', 'name' => 'Page']);
// Create "category" vocabulary
$this->categoriesVocabulary = Vocabulary::create(['name' => 'Categories', 'vid' => 'category']);
$this->categoriesVocabulary->save();
}
/**
* Test condition plugin "term_depth".
*
* @covers \Drupal\improvements_taxonomy\Plugin\Condition\TermDepth
*/
public function testConditionTermDepth(): void {
$condition_manager = $this->container->get('plugin.manager.condition'); /** @var ConditionManager $condition_manager */
$term_depth_condition = $condition_manager->createInstance('term_depth'); /** @var ConditionInterface $term_depth_condition */
$term1 = $this->createTerm($this->categoriesVocabulary, ['name' => 'Term 1 for test ' . __FUNCTION__]);
$term1 = Term::load($term1->id());
$term2 = $this->createTerm($this->categoriesVocabulary, ['name' => 'Term 2 for test ' . __FUNCTION__, 'parent' => [$term1->id()]]);
$term2 = Term::load($term2->id());
$term_depth_condition->setContextValue('taxonomy_term', $term1);
$term_depth_condition->setConfig('depth', []);
$this->assertSame(TRUE, $term_depth_condition->evaluate());
$term_depth_condition->setContextValue('taxonomy_term', $term1);
$term_depth_condition->setConfig('depth', [0]);
$this->assertSame(TRUE, $term_depth_condition->evaluate());
$term_depth_condition->setContextValue('taxonomy_term', $term1);
$term_depth_condition->setConfig('depth', [0, 1, 2]);
$this->assertSame(TRUE, $term_depth_condition->evaluate());
$term_depth_condition->setContextValue('taxonomy_term', $term1);
$term_depth_condition->setConfig('depth', [1]);
$this->assertSame(FALSE, $term_depth_condition->evaluate());
$term_depth_condition->setContextValue('taxonomy_term', $term2);
$term_depth_condition->setConfig('depth', [0]);
$this->assertSame(FALSE, $term_depth_condition->evaluate());
$term_depth_condition->setContextValue('taxonomy_term', $term2);
$term_depth_condition->setConfig('depth', [1]);
$this->assertSame(TRUE, $term_depth_condition->evaluate());
$term_depth_condition->setContextValue('taxonomy_term', $term2);
$term_depth_condition->setConfig('depth', [2]);
$this->assertSame(FALSE, $term_depth_condition->evaluate());
$term_depth_condition->setContextValue('taxonomy_term', $term2);
$term_depth_condition->setConfig('depth', [0, 2]);
$this->assertSame(FALSE, $term_depth_condition->evaluate());
}
/**
* Test Pathauto "term depth" condition.
*/
public function testPathautoTermDepthCondition(): void {
$this->installModule('path', 'pathauto');
$this->drupalLoginAsRoot();
$web_assert = $this->assertSession();
$pathauto_pattern = PathautoPattern::create([
'id' => 'term',
'label' => 'Term',
'type' => 'canonical_entities:taxonomy_term',
'pattern' => 'term/[term:tid]',
]);
$pathauto_pattern->save();
$this->drupalGet('/admin/config/search/path/patterns/' . $pathauto_pattern->id());
$this->dontSeeErrorMessage();
$web_assert->pageTextContains('Term depth condition');
$web_assert->elementExists('css', 'input[name="depth_condition[depth][0]"]');
$web_assert->elementExists('css', 'input[name="depth_condition[depth][1]"]');
$web_assert->elementExists('css', 'input[name="depth_condition[depth][2]"]');
$this->submitForm([
'depth_condition[depth][0]' => TRUE,
], 'Save');
$this->dontSeeErrorMessage();
$this->drupalGet('/admin/config/search/path/patterns/' . $pathauto_pattern->id());
$this->dontSeeErrorMessage();
$web_assert->checkboxChecked('depth_condition[depth][0]');
$term1 = $this->createTerm($this->categoriesVocabulary, ['name' => 'Term 1 for test _testPathautoTermDepthCondition']);
$term1 = Term::load($term1->id());
$this->assertSame('/term/' . $term1->id(), $term1->get('path')->alias);
$term2 = $this->createTerm($this->categoriesVocabulary, ['name' => 'Term 2 for test _testPathautoTermDepthCondition', 'parent' => $term1->id()]);
$term2 = Term::load($term2->id());
$this->assertSame(NULL, $term2->get('path')->alias);
}
/**
* Test "stored_depth" tem field.
*/
public function testTermFieldStoredDepth(): void {
$term1 = $this->createTerm($this->categoriesVocabulary, ['name' => 'Term 1 for test ' . __FUNCTION__]);
$this->assertSame(0, $term1->get('stored_depth')->value);
$this->assertSame(0, TaxonomyHelper::getTermDepth($term1));
$term2 = $this->createTerm($this->categoriesVocabulary, [
'name' => 'Term 2 for test ' . __FUNCTION__,
'parent' => [$term1->id()],
]);
$this->assertSame(1, $term2->get('stored_depth')->value);
$this->assertSame(1, TaxonomyHelper::getTermDepth($term2));
$term3 = $this->createTerm($this->categoriesVocabulary, [
'name' => 'Term 3 for test _testTermDepth',
'parent' => [$term2->id()],
]);
$term4 = $this->createTerm($this->categoriesVocabulary, [
'name' => 'Term 4 for test _testTermDepth',
'parent' => [$term2->id()],
]);
$this->assertSame(2, $term3->get('stored_depth')->value);
$this->assertSame(2, $term4->get('stored_depth')->value);
$this->assertSame(2, TaxonomyHelper::getTermDepth($term3));
$this->assertSame(2, TaxonomyHelper::getTermDepth($term3));
$term2->set('parent', [0]);
$term2->save();
$this->assertSame(0, $term2->get('stored_depth')->value);
$this->assertSame(0, TaxonomyHelper::getTermDepth($term2));
$term3 = Term::load($term3->id()); // Load actual term
$term4 = Term::load($term4->id()); // Load actual term
$this->assertSame(1, (int)$term3->get('stored_depth')->value);
$this->assertSame(1, (int)$term4->get('stored_depth')->value);
$this->assertSame(1, TaxonomyHelper::getTermDepth($term3));
$this->assertSame(1, TaxonomyHelper::getTermDepth($term4));
}
/**
* Test "has_children" term field.
*/
public function testTermFieldHasChildren(): void {
$term_1 = $this->createTerm($this->categoriesVocabulary);
$this->assertFalse((bool)$term_1->get('has_children')->value);
$this->assertFalse(TaxonomyHelper::termHasChilds($term_1->id()));
$term_1_1 = $this->createTerm($this->categoriesVocabulary, ['parent' => $term_1->id()]);
$this->assertFalse((bool)$term_1_1->get('has_children')->value);
$this->assertFalse(TaxonomyHelper::termHasChilds($term_1_1->id()));
$term_1 = Term::load($term_1->id()); // Load actual term
$this->assertTrue((bool)$term_1->get('has_children')->value);
$this->assertTrue(TaxonomyHelper::termHasChilds($term_1->id(), TRUE));
$term_1_1->delete();
$term_1 = Term::load($term_1->id()); // Load actual term
$this->assertFalse((bool)$term_1->get('has_children')->value);
$this->assertFalse(TaxonomyHelper::termHasChilds($term_1->id(), TRUE));
}
/**
* Test taxonomy improvements.
*/
public function testTaxonomyImprovements(): void {
$this->drupalLoginAsRoot();
$web_assert = $this->assertSession();
$this->drupalGet('/admin/structure/taxonomy/manage/' . $this->categoriesVocabulary->id() . '/add');
$this->dontSeeErrorMessage();
$web_assert->elementAttributeExists('css', 'input[name="name[0][value]"]', 'autofocus');
$term = $this->createTerm($this->categoriesVocabulary, ['name' => 'Term for test ' . __FUNCTION__]);
$this->drupalGet('/admin/structure/taxonomy/manage/' . $this->categoriesVocabulary->id() . '/overview');
$this->dontSeeErrorMessage();
$web_assert->elementNotExists('css', '#edit-reset-alphabetical');
$this->installModule('block');
$this->placeBlock('local_tasks_block', [
'id' => 'local_tasks_block',
'region' => 'help',
'weight' => 3,
]);
$this->drupalGet('/admin/structure/taxonomy/manage/category/overview');
$this->dontSeeErrorMessage();
$web_assert->elementTextContains('css', '#block-local-tasks-block a[href="/admin/structure/taxonomy/manage/category/overview"]', 'Terms');
$web_assert->elementTextContains('css', '#block-local-tasks-block a[href="/admin/structure/taxonomy/manage/category"]', 'Edit vocabulary');
}
/**
* Test parent_term cache context.
*
* @covers \Drupal\improvements_taxonomy\Cache\ParentTermCacheContext
*/
public function testCacheContextParentTerm(): void {
$term1 = $this->createTerm($this->categoriesVocabulary, ['name' => 'Term 1 for test _testCacheContextParentTerm']);
$term2 = $this->createTerm($this->categoriesVocabulary, ['name' => 'Term 2 for test _testCacheContextParentTerm', 'parent' => [$term1->id()]]);
$route = new Route('/taxonomy/term/{taxonomy_term}');
$route_match = new RouteMatch('entity.taxonomy_term.canonical', $route, ['taxonomy_term' => $term2], ['taxonomy_term' => $term2->id()]);
$cache_context = new ParentTermCacheContext($route_match);
$this->assertSame((string)$term1->id(), $cache_context->getContext());
$term3 = $this->createTerm($this->categoriesVocabulary, ['name' => 'Term 3 for test _testCacheContextParentTerm']);
$term2->set('parent', [$term1->id(), $term3->id()]);
$term2->save();
$this->assertSame($term1->id() . ',' . $term3->id(), $cache_context->getContext());
$route = new Route('/');
$route_match = new RouteMatch('<front>', $route);
$cache_context = new ParentTermCacheContext($route_match);
$this->assertSame('', $cache_context->getContext());
}
/**
* Test tokens [site:third_party_setting_name].
*/
public function testTokenTermParentsField(): void {
$this->installModule('token');
$token_service = $this->container->get('token');
$term_1 = $this->createTerm($this->categoriesVocabulary, ['name' => 'Term 1 for test ' . __FUNCTION__]);
$term_1_1 = $this->createTerm($this->categoriesVocabulary, ['name' => 'Term 1.1 for test ' . __FUNCTION__, 'parent' => $term_1->id()]);
$term_1_2 = $this->createTerm($this->categoriesVocabulary, ['name' => 'Term 1.2 for test ' . __FUNCTION__, 'parent' => $term_1->id()]);
$term_1_1_1 = $this->createTerm($this->categoriesVocabulary, ['name' => 'Term 1.1.1 for test ' . __FUNCTION__, 'parent' => $term_1_1->id()]);
$this->assertEquals("{$term_1->label()}, {$term_1_1->label()}", $token_service->replace('[term:parents_field:name]', ['term' => $term_1_1_1]));
$this->assertEquals("{$term_1->label()}/{$term_1_1->label()}", $token_service->replace('[term:parents_field:name:join:/]', ['term' => $term_1_1_1]));
$this->assertEquals("{$term_1->id()}, {$term_1_1->id()}", $token_service->replace('[term:parents_field:tid]', ['term' => $term_1_1_1]));
$this->assertEquals("{$term_1->id()}", $token_service->replace('[term:parents_field:tid]', ['term' => $term_1_1]));
$this->assertEquals('', $token_service->replace('[term:parents_field:tid]', ['term' => $term_1]));
$this->assertEquals("{$term_1->label()}/{$term_1_1->label()}/{$term_1_1_1->label()}", $token_service->replace('[term:parents_field:name:join:/]/[term:name]', ['term' => $term_1_1_1]));
}
}
