View source
<?php
namespace Drupal\Tests\content_moderation\Functional;
use Drupal\node\Entity\NodeType;
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
use Drupal\Tests\views\Functional\ViewTestBase;
use Drupal\views\Entity\View;
use Drupal\views\ViewEntityInterface;
use Drupal\workflows\Entity\Workflow;
class ViewsModerationStateFilterTest extends ViewTestBase {
use ContentModerationTestTrait;
protected static $modules = [
'node',
'content_moderation',
'workflows',
'workflow_type_test',
'entity_test',
'language',
'content_translation',
'views_ui',
];
protected $defaultTheme = 'stark';
protected function setUp($import_test_views = TRUE) : void {
parent::setUp(FALSE);
NodeType::create([
'type' => 'example_a',
])
->save();
NodeType::create([
'type' => 'example_b',
])
->save();
NodeType::create([
'type' => 'example_c',
])
->save();
$this
->createEditorialWorkflow();
$new_workflow = Workflow::create([
'type' => 'content_moderation',
'id' => 'new_workflow',
'label' => 'New workflow',
]);
$new_workflow
->getTypePlugin()
->addState('bar', 'Bar');
$new_workflow
->getTypePlugin()
->addEntityTypeAndBundle('node', 'example_c');
$new_workflow
->save();
$this
->drupalLogin($this
->drupalCreateUser([
'administer workflows',
'administer views',
]));
$this->container
->get('module_installer')
->install([
'content_moderation_test_views',
]);
$new_workflow
->getTypePlugin()
->removeEntityTypeAndBundle('node', 'example_c');
$new_workflow
->save();
}
public function testModerationStateFilterDependencyHandling() {
$view_id = 'test_content_moderation_state_filter_base_table';
$view = View::load($view_id);
$this
->assertWorkflowDependencies([], $view);
$this
->assertTrue($view
->status());
$this
->drupalGet('admin/config/workflow/workflows/manage/editorial/type/node');
$this
->submitForm([
'bundles[example_a]' => TRUE,
], 'Save');
$edit['options[value][]'] = [
'editorial-published',
];
$this
->drupalGet("admin/structure/views/nojs/handler/{$view_id}/default/filter/moderation_state");
$this
->submitForm($edit, 'Apply');
$this
->drupalGet("admin/structure/views/view/{$view_id}");
$this
->submitForm([], 'Save');
$view = $this
->loadViewUnchanged($view_id);
$this
->assertWorkflowDependencies([
'editorial',
], $view);
$this
->assertTrue($view
->status());
$this
->drupalGet('admin/config/workflow/workflows/add');
$this
->submitForm([
'label' => 'Translation',
'id' => 'translation',
'workflow_type' => 'content_moderation',
], 'Save');
$this
->drupalGet('admin/config/workflow/workflows/manage/translation/add_state');
$this
->submitForm([
'label' => 'Needs Review',
'id' => 'needs_review',
], 'Save');
$this
->drupalGet('admin/config/workflow/workflows/manage/translation/type/node');
$this
->submitForm([
'bundles[example_b]' => TRUE,
], 'Save');
$edit['options[value][]'] = [
'editorial-published',
'translation-needs_review',
];
$this
->drupalGet("admin/structure/views/nojs/handler/{$view_id}/default/filter/moderation_state");
$this
->submitForm($edit, 'Apply');
$this
->drupalGet("admin/structure/views/view/{$view_id}");
$this
->submitForm([], 'Save');
$view = $this
->loadViewUnchanged($view_id);
$this
->assertWorkflowDependencies([
'editorial',
'translation',
], $view);
$this
->assertTrue(isset($view
->getDisplay('default')['display_options']['filters']['moderation_state']));
$this
->assertTrue($view
->status());
$this
->drupalGet('admin/config/workflow/workflows/manage/translation/delete');
$this
->submitForm([], 'Delete');
$view = $this
->loadViewUnchanged($view_id);
$this
->assertFalse($view
->status());
$this
->assertFalse(isset($view
->getDisplay('default')['display_options']['filters']['moderation_state']));
$this
->drupalGet("admin/structure/views/view/{$view_id}");
$this
->submitForm([], 'Save');
$this
->assertWorkflowDependencies([], $view);
}
public function loadViewUnchanged($view_id) {
$this->container
->get('cache.config')
->deleteAll();
$this->container
->get('config.factory')
->reset();
return $this->container
->get('entity_type.manager')
->getStorage('view')
->loadUnchanged($view_id);
}
public function testWorkflowChanges($view_id) {
$this
->drupalGet('admin/config/workflow/workflows/manage/editorial/type/node');
$this
->submitForm([
'bundles[example_a]' => TRUE,
'bundles[example_b]' => TRUE,
], 'Save');
\Drupal::service('entity_type.bundle.info')
->clearCachedBundles();
$this
->drupalGet("admin/structure/views/nojs/handler/{$view_id}/default/filter/moderation_state");
$this
->submitForm([], 'Hide filter');
$this
->drupalGet("admin/structure/views/view/{$view_id}");
$this
->submitForm([], 'Save');
$this
->createNode([
'type' => 'example_a',
'moderation_state' => 'published',
]);
$this
->createNode([
'type' => 'example_b',
'moderation_state' => 'published',
]);
$archived_node_a = $this
->createNode([
'type' => 'example_a',
'moderation_state' => 'archived',
]);
$archived_node_b = $this
->createNode([
'type' => 'example_b',
'moderation_state' => 'archived',
]);
$edit['options[value][]'] = [
'editorial-archived',
];
$this
->drupalGet("admin/structure/views/nojs/handler/{$view_id}/default/filter/moderation_state");
$this
->submitForm($edit, 'Apply');
$this
->drupalGet("admin/structure/views/view/{$view_id}");
$this
->submitForm([], 'Save');
$view = $this
->loadViewUnchanged($view_id);
$this
->executeAndAssertIdenticalResultset($view, [
[
'nid' => $archived_node_a
->id(),
],
[
'nid' => $archived_node_b
->id(),
],
], [
'nid' => 'nid',
]);
$this
->drupalGet('admin/config/workflow/workflows/manage/editorial/type/node');
$this
->submitForm([
'bundles[example_a]' => TRUE,
'bundles[example_b]' => FALSE,
], 'Save');
\Drupal::service('entity_type.bundle.info')
->clearCachedBundles();
$view = $this
->loadViewUnchanged($view_id);
$this
->executeAndAssertIdenticalResultset($view, [
[
'nid' => $archived_node_a
->id(),
],
], [
'nid' => 'nid',
]);
$this
->drupalGet("admin/structure/views/view/{$view_id}");
$this
->submitForm([], 'Save');
$this
->drupalGet('admin/config/workflow/workflows/manage/editorial/type/node');
$this
->submitForm([
'bundles[example_a]' => FALSE,
'bundles[example_b]' => FALSE,
], 'Save');
\Drupal::service('entity_type.bundle.info')
->clearCachedBundles();
$view = $this
->loadViewUnchanged($view_id);
$this
->executeAndAssertIdenticalResultset($view, [], []);
$this
->drupalGet("admin/structure/views/view/{$view_id}");
$this
->submitForm([], 'Save');
$this
->assertSession()
->pageTextContains("Broken/missing handler");
}
protected function executeAndAssertIdenticalResultset(ViewEntityInterface $view_entity, $expected, $column_map) {
$executable = $this->container
->get('views.executable')
->get($view_entity);
$this
->executeView($executable);
$this
->assertIdenticalResultset($executable, $expected, $column_map);
}
public function providerTestWorkflowChanges() {
return [
'view on base table, filter on base table' => [
'test_content_moderation_state_filter_base_table',
],
'view on base table, filter on revision table' => [
'test_content_moderation_state_filter_base_table_filter_on_revision',
],
];
}
public function testFilterRenderCache() {
$this
->drupalGet('admin/config/workflow/workflows/manage/editorial/type/node');
$this
->submitForm([
'bundles[example_a]' => TRUE,
], 'Save');
$this
->assertFilterStates([
'All',
'editorial-draft',
'editorial-published',
'editorial-archived',
]);
$this
->drupalGet('admin/config/workflow/workflows/manage/editorial/add_state');
$this
->submitForm([
'label' => 'Foo',
'id' => 'foo',
], 'Save');
$this
->assertFilterStates([
'All',
'editorial-draft',
'editorial-published',
'editorial-archived',
'editorial-foo',
]);
$this
->drupalGet('admin/config/workflow/workflows/manage/new_workflow/type/node');
$this
->submitForm([
'bundles[example_b]' => TRUE,
], 'Save');
$this
->assertFilterStates([
'All',
'editorial-draft',
'editorial-published',
'editorial-archived',
'editorial-foo',
'new_workflow-draft',
'new_workflow-published',
'new_workflow-bar',
]);
$this
->drupalGet('admin/config/workflow/workflows/manage/editorial/add_state');
$this
->submitForm([
'label' => 'Foo 2',
'id' => 'foo2',
], 'Save');
$this
->drupalGet('admin/config/workflow/workflows/manage/editorial/add_state');
$this
->submitForm([
'label' => 'Foo 3',
'id' => 'foo3',
], 'Save');
$view_id = 'test_content_moderation_state_filter_base_table';
$edit['options[expose][multiple]'] = TRUE;
$this
->drupalGet("admin/structure/views/nojs/handler/{$view_id}/default/filter/moderation_state");
$this
->submitForm($edit, 'Apply');
$this
->drupalGet("admin/structure/views/view/{$view_id}");
$this
->submitForm([], 'Save');
$this
->assertFilterStates([
'editorial-draft',
'editorial-published',
'editorial-archived',
'editorial-foo',
'editorial-foo2',
'editorial-foo3',
'new_workflow-draft',
'new_workflow-published',
'new_workflow-bar',
], TRUE);
}
protected function assertFilterStates($states, $check_size = FALSE) {
$this
->drupalGet('/filter-test-path');
$assert_session = $this
->assertSession();
$assert_session
->elementsCount('css', '#edit-default-revision-state option', count($states));
if ($check_size) {
$this
->assertGreaterThan(8, count($states));
$assert_session
->elementAttributeContains('css', '#edit-default-revision-state', 'size', 8);
}
foreach ($states as $state) {
$assert_session
->optionExists('Default Revision State', $state);
}
}
protected function assertWorkflowDependencies(array $workflow_ids, ViewEntityInterface $view) {
$dependencies = $view
->getDependencies();
$expected = [];
foreach (Workflow::loadMultiple($workflow_ids) as $workflow) {
$expected[] = $workflow
->getConfigDependencyName();
}
if ($expected) {
$this
->assertSame($expected, $dependencies['config']);
}
else {
$this
->assertTrue(!isset($dependencies['config']));
}
}
}