Issue #2915383 by Sam152, amateescu, jibran: The moderation_state base field is added to all revisionable entity types even if they do not have moderation enabled
parent
3ba6bc1168
commit
ba726bed0c
|
@ -21,6 +21,9 @@ use Drupal\Core\Form\FormStateInterface;
|
|||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\views\Plugin\views\filter\Broken;
|
||||
use Drupal\views\ViewExecutable;
|
||||
use Drupal\views\Views;
|
||||
use Drupal\workflows\WorkflowInterface;
|
||||
use Drupal\Core\Action\Plugin\Action\PublishAction;
|
||||
use Drupal\Core\Action\Plugin\Action\UnpublishAction;
|
||||
|
@ -64,6 +67,20 @@ function content_moderation_entity_base_field_info(EntityTypeInterface $entity_t
|
|||
->entityBaseFieldInfo($entity_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_bundle_field_info().
|
||||
*/
|
||||
function content_moderation_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
|
||||
if (isset($base_field_definitions['moderation_state'])) {
|
||||
// Add the target bundle to the moderation state field. Since each bundle
|
||||
// can be attached to a different moderation workflow, adding this
|
||||
// information to the field definition allows the associated workflow to be
|
||||
// derived where a field definition is present.
|
||||
$base_field_definitions['moderation_state']->setTargetBundle($bundle);
|
||||
return $base_field_definitions;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_entity_type_alter().
|
||||
*/
|
||||
|
@ -316,6 +333,10 @@ function content_moderation_workflow_insert(WorkflowInterface $entity) {
|
|||
\Drupal::service('entity_type.bundle.info')->clearCachedBundles();
|
||||
// Clear field cache so extra field is added or removed.
|
||||
\Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();
|
||||
// Clear the views data cache so the extra field is available in views.
|
||||
if (\Drupal::moduleHandler()->moduleExists('views')) {
|
||||
Views::viewsData()->clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -327,4 +348,22 @@ function content_moderation_workflow_update(WorkflowInterface $entity) {
|
|||
\Drupal::service('entity_type.bundle.info')->clearCachedBundles();
|
||||
// Clear field cache so extra field is added or removed.
|
||||
\Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();
|
||||
// Clear the views data cache so the extra field is available in views.
|
||||
if (\Drupal::moduleHandler()->moduleExists('views')) {
|
||||
Views::viewsData()->clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_views_post_execute().
|
||||
*/
|
||||
function content_moderation_views_post_execute(ViewExecutable $view) {
|
||||
// @todo, remove this once broken handlers in views configuration result in
|
||||
// a view no longer returning results. https://www.drupal.org/node/2907954.
|
||||
foreach ($view->filter as $id => $filter) {
|
||||
if (strpos($id, 'moderation_state') === 0 && $filter instanceof Broken) {
|
||||
$view->result = [];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
use Drupal\Core\Config\Entity\ConfigEntityUpdater;
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\views\Entity\View;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
|
@ -138,3 +139,34 @@ function content_moderation_post_update_set_views_filter_latest_translation_affe
|
|||
$view->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the dependencies of entity displays to include associated workflow.
|
||||
*/
|
||||
function content_moderation_post_update_entity_display_dependencies(&$sandbox) {
|
||||
/** @var \Drupal\content_moderation\ModerationInformationInterface $moderation_info */
|
||||
$moderation_info = \Drupal::service('content_moderation.moderation_information');
|
||||
/** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
|
||||
$entity_type_manager = \Drupal::service('entity_type.manager');
|
||||
|
||||
\Drupal::classResolver(ConfigEntityUpdater::class)->update($sandbox, 'entity_form_display', function (EntityFormDisplay $entity_form_display) use ($moderation_info, $entity_type_manager) {
|
||||
$associated_entity_type = $entity_type_manager->getDefinition($entity_form_display->getTargetEntityTypeId());
|
||||
|
||||
if ($moderation_info->isModeratedEntityType($associated_entity_type)) {
|
||||
$entity_form_display->calculateDependencies();
|
||||
return TRUE;
|
||||
}
|
||||
elseif ($moderation_state_component = $entity_form_display->getComponent('moderation_state')) {
|
||||
// Remove the component from the entity form display, then manually delete
|
||||
// it from the hidden components list, completely purging it.
|
||||
$entity_form_display->removeComponent('moderation_state');
|
||||
$hidden_components = $entity_form_display->get('hidden');
|
||||
unset($hidden_components['moderation_state']);
|
||||
$entity_form_display->set('hidden', $hidden_components);
|
||||
$entity_form_display->calculateDependencies();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -240,7 +240,7 @@ class EntityTypeInfo implements ContainerInjectionInterface {
|
|||
* @see hook_entity_base_field_info()
|
||||
*/
|
||||
public function entityBaseFieldInfo(EntityTypeInterface $entity_type) {
|
||||
if (!$this->moderationInfo->canModerateEntitiesOfEntityType($entity_type)) {
|
||||
if (!$this->moderationInfo->isModeratedEntityType($entity_type)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,14 @@ class ModerationInformation implements ModerationInformationInterface {
|
|||
return $this->shouldModerateEntitiesOfBundle($entity->getEntityType(), $entity->bundle());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isModeratedEntityType(EntityTypeInterface $entity_type) {
|
||||
$bundles = $this->bundleInfo->getBundleInfo($entity_type->id());
|
||||
return !empty(array_column($bundles, 'workflow'));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -206,10 +214,17 @@ class ModerationInformation implements ModerationInformationInterface {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWorkflowForEntity(ContentEntityInterface $entity) {
|
||||
$bundles = $this->bundleInfo->getBundleInfo($entity->getEntityTypeId());
|
||||
if (isset($bundles[$entity->bundle()]['workflow'])) {
|
||||
return $this->entityTypeManager->getStorage('workflow')->load($bundles[$entity->bundle()]['workflow']);
|
||||
};
|
||||
return $this->getWorkflowForEntityTypeAndBundle($entity->getEntityTypeId(), $entity->bundle());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getWorkflowForEntityTypeAndBundle($entity_type_id, $bundle_id) {
|
||||
$bundles = $this->bundleInfo->getBundleInfo($entity_type_id);
|
||||
if (isset($bundles[$bundle_id]['workflow'])) {
|
||||
return $this->entityTypeManager->getStorage('workflow')->load($bundles[$bundle_id]['workflow']);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,17 @@ interface ModerationInformationInterface {
|
|||
*/
|
||||
public function shouldModerateEntitiesOfBundle(EntityTypeInterface $entity_type, $bundle);
|
||||
|
||||
/**
|
||||
* Determines if an entity type has at least one moderated bundle.
|
||||
*
|
||||
* @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
|
||||
* The entity type definition to check.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if an entity type has a moderated bundle, FALSE otherwise.
|
||||
*/
|
||||
public function isModeratedEntityType(EntityTypeInterface $entity_type);
|
||||
|
||||
/**
|
||||
* Loads the latest revision of a specific entity.
|
||||
*
|
||||
|
@ -163,6 +174,19 @@ interface ModerationInformationInterface {
|
|||
*/
|
||||
public function getWorkflowForEntity(ContentEntityInterface $entity);
|
||||
|
||||
/**
|
||||
* Gets the workflow for the given entity type and bundle.
|
||||
*
|
||||
* @param string $entity_type_id
|
||||
* The entity type ID.
|
||||
* @param string $bundle_id
|
||||
* The entity bundle ID.
|
||||
*
|
||||
* @return \Drupal\workflows\WorkflowInterface|null
|
||||
* The associated workflow. NULL if there is no workflow.
|
||||
*/
|
||||
public function getWorkflowForEntityTypeAndBundle($entity_type_id, $bundle_id);
|
||||
|
||||
/**
|
||||
* Gets unsupported features for a given entity type.
|
||||
*
|
||||
|
|
|
@ -178,4 +178,15 @@ class ModerationStateWidget extends OptionsSelectWidget implements ContainerFact
|
|||
return is_a($field_definition->getClass(), ModerationStateFieldItemList::class, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function calculateDependencies() {
|
||||
$dependencies = parent::calculateDependencies();
|
||||
if ($workflow = $this->moderationInformation->getWorkflowForEntityTypeAndBundle($this->fieldDefinition->getTargetEntityTypeId(), $this->fieldDefinition->getTargetBundle())) {
|
||||
$dependencies[$workflow->getConfigDependencyKey()][] = $workflow->getConfigDependencyName();
|
||||
}
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ class ViewsData {
|
|||
$data = [];
|
||||
|
||||
$entity_types_with_moderation = array_filter($this->entityTypeManager->getDefinitions(), function (EntityTypeInterface $type) {
|
||||
return $this->moderationInformation->canModerateEntitiesOfEntityType($type);
|
||||
return $this->moderationInformation->isModeratedEntityType($type);
|
||||
});
|
||||
|
||||
// Provides a relationship from moderated entity to its moderation state
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
// @codingStandardsIgnoreFile
|
||||
/**
|
||||
* @file
|
||||
* Content for the update path test in #2915383.
|
||||
*
|
||||
* @see \Drupal\Tests\content_moderation\Functional\EntityFormDisplayDependenciesUpdateTest
|
||||
*/
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
$connection->update('config')
|
||||
->fields([
|
||||
'data' => 'a:11:{s:4:"uuid";s:36:"16624d7d-0800-4ed7-9861-41f7e71394a8";s:8:"langcode";s:2:"en";s:6:"status";b:1;s:12:"dependencies";a:2:{s:6:"config";a:2:{i:0;s:24:"block_content.type.basic";i:1;s:36:"field.field.block_content.basic.body";}s:6:"module";a:2:{i:0;s:18:"content_moderation";i:1;s:4:"text";}}s:5:"_core";a:1:{s:19:"default_config_hash";s:43:"e1Nu5xXAuF_QplbBUhQBPLnYWvHtDX0MkZnpuCiY8uM";}s:2:"id";s:27:"block_content.basic.default";s:16:"targetEntityType";s:13:"block_content";s:6:"bundle";s:5:"basic";s:4:"mode";s:7:"default";s:7:"content";a:3:{s:4:"body";a:5:{s:4:"type";s:26:"text_textarea_with_summary";s:6:"weight";i:-4;s:6:"region";s:7:"content";s:8:"settings";a:3:{s:4:"rows";i:9;s:12:"summary_rows";i:3;s:11:"placeholder";s:0:"";}s:20:"third_party_settings";a:0:{}}s:4:"info";a:5:{s:4:"type";s:16:"string_textfield";s:6:"weight";i:-5;s:6:"region";s:7:"content";s:8:"settings";a:2:{s:4:"size";i:60;s:11:"placeholder";s:0:"";}s:20:"third_party_settings";a:0:{}}s:16:"moderation_state";a:5:{s:4:"type";s:24:"moderation_state_default";s:6:"weight";i:100;s:8:"settings";a:0:{}s:6:"region";s:7:"content";s:20:"third_party_settings";a:0:{}}}s:6:"hidden";a:0:{}}',
|
||||
])
|
||||
->condition('name', 'core.entity_form_display.block_content.basic.default')
|
||||
->execute();
|
||||
|
||||
$connection->update('config')
|
||||
->fields([
|
||||
'data' => 'a:11:{s:4:"uuid";s:36:"af6ca931-0ecc-46c0-8097-ffb383db6287";s:8:"langcode";s:2:"en";s:6:"status";b:1;s:12:"dependencies";a:2:{s:6:"config";a:6:{i:0;s:29:"field.field.node.article.body";i:1;s:32:"field.field.node.article.comment";i:2;s:36:"field.field.node.article.field_image";i:3;s:35:"field.field.node.article.field_tags";i:4;s:21:"image.style.thumbnail";i:5;s:17:"node.type.article";}s:6:"module";a:5:{i:0;s:7:"comment";i:1;s:18:"content_moderation";i:2;s:5:"image";i:3;s:4:"path";i:4;s:4:"text";}}s:5:"_core";a:1:{s:19:"default_config_hash";s:43:"buc38w3gxCqFnjINJhMiJvPpj9jWflKvlKDyBVMPVvw";}s:2:"id";s:20:"node.article.default";s:16:"targetEntityType";s:4:"node";s:6:"bundle";s:7:"article";s:4:"mode";s:7:"default";s:7:"content";a:12:{s:4:"body";a:5:{s:4:"type";s:26:"text_textarea_with_summary";s:6:"weight";i:1;s:6:"region";s:7:"content";s:8:"settings";a:3:{s:4:"rows";i:9;s:12:"summary_rows";i:3;s:11:"placeholder";s:0:"";}s:20:"third_party_settings";a:0:{}}s:7:"comment";a:5:{s:4:"type";s:15:"comment_default";s:6:"weight";i:20;s:6:"region";s:7:"content";s:8:"settings";a:0:{}s:20:"third_party_settings";a:0:{}}s:7:"created";a:5:{s:4:"type";s:18:"datetime_timestamp";s:6:"weight";i:10;s:6:"region";s:7:"content";s:8:"settings";a:0:{}s:20:"third_party_settings";a:0:{}}s:11:"field_image";a:5:{s:4:"type";s:11:"image_image";s:6:"weight";i:4;s:6:"region";s:7:"content";s:8:"settings";a:2:{s:18:"progress_indicator";s:8:"throbber";s:19:"preview_image_style";s:9:"thumbnail";}s:20:"third_party_settings";a:0:{}}s:10:"field_tags";a:5:{s:4:"type";s:34:"entity_reference_autocomplete_tags";s:6:"weight";i:3;s:6:"region";s:7:"content";s:8:"settings";a:3:{s:14:"match_operator";s:8:"CONTAINS";s:4:"size";i:60;s:11:"placeholder";s:0:"";}s:20:"third_party_settings";a:0:{}}s:16:"moderation_state";a:5:{s:4:"type";s:24:"moderation_state_default";s:6:"weight";i:100;s:8:"settings";a:0:{}s:6:"region";s:7:"content";s:20:"third_party_settings";a:0:{}}s:4:"path";a:5:{s:4:"type";s:4:"path";s:6:"weight";i:30;s:6:"region";s:7:"content";s:8:"settings";a:0:{}s:20:"third_party_settings";a:0:{}}s:7:"promote";a:5:{s:4:"type";s:16:"boolean_checkbox";s:8:"settings";a:1:{s:13:"display_label";b:1;}s:6:"weight";i:15;s:6:"region";s:7:"content";s:20:"third_party_settings";a:0:{}}s:6:"status";a:5:{s:4:"type";s:16:"boolean_checkbox";s:8:"settings";a:1:{s:13:"display_label";b:1;}s:6:"weight";i:120;s:6:"region";s:7:"content";s:20:"third_party_settings";a:0:{}}s:6:"sticky";a:5:{s:4:"type";s:16:"boolean_checkbox";s:8:"settings";a:1:{s:13:"display_label";b:1;}s:6:"weight";i:16;s:6:"region";s:7:"content";s:20:"third_party_settings";a:0:{}}s:5:"title";a:5:{s:4:"type";s:16:"string_textfield";s:6:"weight";i:0;s:6:"region";s:7:"content";s:8:"settings";a:2:{s:4:"size";i:60;s:11:"placeholder";s:0:"";}s:20:"third_party_settings";a:0:{}}s:3:"uid";a:5:{s:4:"type";s:29:"entity_reference_autocomplete";s:6:"weight";i:5;s:6:"region";s:7:"content";s:8:"settings";a:3:{s:14:"match_operator";s:8:"CONTAINS";s:4:"size";i:60;s:11:"placeholder";s:0:"";}s:20:"third_party_settings";a:0:{}}}s:6:"hidden";a:0:{}}',
|
||||
])
|
||||
->condition('name', 'core.entity_form_display.node.article.default')
|
||||
->execute();
|
||||
|
||||
$connection->update('config')
|
||||
->fields([
|
||||
'data' => 'a:9:{s:4:"uuid";s:36:"08b548c7-ff59-468b-9347-7d697680d035";s:8:"langcode";s:2:"en";s:6:"status";b:1;s:12:"dependencies";a:2:{s:6:"config";a:2:{i:0;s:17:"node.type.article";i:1;s:14:"node.type.page";}s:6:"module";a:1:{i:0;s:18:"content_moderation";}}s:5:"_core";a:1:{s:19:"default_config_hash";s:43:"T_JxNjYlfoRBi7Bj1zs5Xv9xv1btuBkKp5C1tNrjMhI";}s:2:"id";s:9:"editorial";s:5:"label";s:9:"Editorial";s:4:"type";s:18:"content_moderation";s:13:"type_settings";a:3:{s:6:"states";a:3:{s:8:"archived";a:4:{s:5:"label";s:8:"Archived";s:6:"weight";i:5;s:9:"published";b:0;s:16:"default_revision";b:1;}s:5:"draft";a:4:{s:5:"label";s:5:"Draft";s:9:"published";b:0;s:16:"default_revision";b:0;s:6:"weight";i:-5;}s:9:"published";a:4:{s:5:"label";s:9:"Published";s:9:"published";b:1;s:16:"default_revision";b:1;s:6:"weight";i:0;}}s:11:"transitions";a:5:{s:7:"archive";a:4:{s:5:"label";s:7:"Archive";s:4:"from";a:1:{i:0;s:9:"published";}s:2:"to";s:8:"archived";s:6:"weight";i:2;}s:14:"archived_draft";a:4:{s:5:"label";s:16:"Restore to Draft";s:4:"from";a:1:{i:0;s:8:"archived";}s:2:"to";s:5:"draft";s:6:"weight";i:3;}s:18:"archived_published";a:4:{s:5:"label";s:7:"Restore";s:4:"from";a:1:{i:0;s:8:"archived";}s:2:"to";s:9:"published";s:6:"weight";i:4;}s:16:"create_new_draft";a:4:{s:5:"label";s:16:"Create New Draft";s:2:"to";s:5:"draft";s:6:"weight";i:0;s:4:"from";a:2:{i:0;s:5:"draft";i:1;s:9:"published";}}s:7:"publish";a:4:{s:5:"label";s:7:"Publish";s:2:"to";s:9:"published";s:6:"weight";i:1;s:4:"from";a:2:{i:0;s:5:"draft";i:1;s:9:"published";}}}s:12:"entity_types";a:1:{s:4:"node";a:2:{i:0;s:7:"article";i:1;s:4:"page";}}}}',
|
||||
])
|
||||
->condition('name', 'workflows.workflow.editorial')
|
||||
->execute();
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\content_moderation\Functional;
|
||||
|
||||
use Drupal\Core\Entity\Entity\EntityFormDisplay;
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
|
||||
/**
|
||||
* Test updating the dependencies of entity form displays.
|
||||
*
|
||||
* @group Update
|
||||
* @group legacy
|
||||
*
|
||||
* @see content_moderation_post_update_entity_display_dependencies()
|
||||
*/
|
||||
class EntityFormDisplayDependenciesUpdateTest extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../system/tests/fixtures/update/drupal-8.4.0.bare.standard.php.gz',
|
||||
__DIR__ . '/../../fixtures/update/drupal-8.4.0-content_moderation_installed.php',
|
||||
__DIR__ . '/../../fixtures/update/drupal-8.entity-form-display-dependencies-2915383.php',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests updating the dependencies of entity displays.
|
||||
*/
|
||||
public function testEntityDisplaysUpdated() {
|
||||
$no_moderation_form_display = EntityFormDisplay::load('block_content.basic.default');
|
||||
$has_moderation_form_display = EntityFormDisplay::load('node.article.default');
|
||||
|
||||
// Assert the moderation field and content_moderation dependency exists on
|
||||
// an entity type that does not have moderation enabled, these will be
|
||||
// removed.
|
||||
$this->assertEquals('moderation_state_default', $no_moderation_form_display->getComponent('moderation_state')['type']);
|
||||
$this->assertTrue(in_array('content_moderation', $no_moderation_form_display->getDependencies()['module']));
|
||||
|
||||
// Assert the editorial config dependency doesn't exist on the entity form
|
||||
// with moderation, this will be added.
|
||||
$this->assertFalse(in_array('workflows.workflow.editorial', $has_moderation_form_display->getDependencies()['config']));
|
||||
|
||||
$this->runUpdates();
|
||||
|
||||
$no_moderation_form_display = EntityFormDisplay::load('block_content.basic.default');
|
||||
$has_moderation_form_display = EntityFormDisplay::load('node.article.default');
|
||||
|
||||
// The moderation_state field has been removed from the non-moderated block
|
||||
// entity form display.
|
||||
$this->assertEquals(NULL, $no_moderation_form_display->getComponent('moderation_state'));
|
||||
$this->assertFalse(in_array('content_moderation', $no_moderation_form_display->getDependencies()['module']));
|
||||
|
||||
// The editorial workflow config dependency has been added to moderated
|
||||
// form display.
|
||||
$this->assertTrue(in_array('workflows.workflow.editorial', $has_moderation_form_display->getDependencies()['config']));
|
||||
}
|
||||
|
||||
}
|
|
@ -20,17 +20,33 @@ class ModerationStateAccessTest extends BrowserTestBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'content_moderation_test_views',
|
||||
'content_moderation',
|
||||
'node',
|
||||
];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$node_type = NodeType::create([
|
||||
'type' => 'test',
|
||||
'label' => 'Test',
|
||||
]);
|
||||
$node_type->save();
|
||||
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'test');
|
||||
$workflow->save();
|
||||
|
||||
$this->container->get('module_installer')->install(['content_moderation_test_views']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the view operation access handler with the view permission.
|
||||
*/
|
||||
public function testViewShowsCorrectStates() {
|
||||
$node_type_id = 'test';
|
||||
$this->createNodeType('Test', $node_type_id);
|
||||
|
||||
$permissions = [
|
||||
'access content',
|
||||
'view all revisions',
|
||||
|
@ -39,7 +55,7 @@ class ModerationStateAccessTest extends BrowserTestBase {
|
|||
$this->drupalLogin($editor1);
|
||||
|
||||
$node_1 = Node::create([
|
||||
'type' => $node_type_id,
|
||||
'type' => 'test',
|
||||
'title' => 'Draft node',
|
||||
'uid' => $editor1->id(),
|
||||
]);
|
||||
|
@ -47,7 +63,7 @@ class ModerationStateAccessTest extends BrowserTestBase {
|
|||
$node_1->save();
|
||||
|
||||
$node_2 = Node::create([
|
||||
'type' => $node_type_id,
|
||||
'type' => 'test',
|
||||
'title' => 'Published node',
|
||||
'uid' => $editor1->id(),
|
||||
]);
|
||||
|
@ -82,29 +98,4 @@ class ModerationStateAccessTest extends BrowserTestBase {
|
|||
$this->assertFalse($page->hasContent('Published'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new node type.
|
||||
*
|
||||
* @param string $label
|
||||
* The human-readable label of the type to create.
|
||||
* @param string $machine_name
|
||||
* The machine name of the type to create.
|
||||
*
|
||||
* @return \Drupal\node\Entity\NodeType
|
||||
* The node type just created.
|
||||
*/
|
||||
protected function createNodeType($label, $machine_name) {
|
||||
/** @var \Drupal\node\Entity\NodeType $node_type */
|
||||
$node_type = NodeType::create([
|
||||
'type' => $machine_name,
|
||||
'label' => $label,
|
||||
]);
|
||||
$node_type->save();
|
||||
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', $machine_name);
|
||||
$workflow->save();
|
||||
return $node_type;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ class ModerationStateNodeTest extends ModerationStateTestBase {
|
|||
if (!$node) {
|
||||
$this->fail('Non-moderated test node was not saved correctly.');
|
||||
}
|
||||
$this->assertEqual(NULL, $node->moderation_state->value);
|
||||
$this->assertFalse($node->hasField('moderation_state'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,8 +5,8 @@ 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\ViewExecutable;
|
||||
use Drupal\views\Views;
|
||||
use Drupal\views\Entity\View;
|
||||
use Drupal\views\ViewEntityInterface;
|
||||
use Drupal\workflows\Entity\Workflow;
|
||||
|
||||
/**
|
||||
|
@ -24,7 +24,6 @@ class ViewsModerationStateFilterTest extends ViewTestBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public static $modules = [
|
||||
'content_moderation_test_views',
|
||||
'node',
|
||||
'content_moderation',
|
||||
'workflows',
|
||||
|
@ -47,6 +46,9 @@ class ViewsModerationStateFilterTest extends ViewTestBase {
|
|||
NodeType::create([
|
||||
'type' => 'example_b',
|
||||
])->save();
|
||||
NodeType::create([
|
||||
'type' => 'example_c',
|
||||
])->save();
|
||||
|
||||
$this->createEditorialWorkflow();
|
||||
|
||||
|
@ -56,9 +58,15 @@ class ViewsModerationStateFilterTest extends ViewTestBase {
|
|||
'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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,10 +79,10 @@ class ViewsModerationStateFilterTest extends ViewTestBase {
|
|||
// First, check that the view doesn't have any config dependency when there
|
||||
// are no states configured in the filter.
|
||||
$view_id = 'test_content_moderation_state_filter_base_table';
|
||||
$view = Views::getView($view_id);
|
||||
$view = View::load($view_id);
|
||||
|
||||
$this->assertWorkflowDependencies([], $view);
|
||||
$this->assertTrue($view->storage->status());
|
||||
$this->assertTrue($view->status());
|
||||
|
||||
// Configure the Editorial workflow for a node bundle, set the filter value
|
||||
// to use one of its states and check that the workflow is now a dependency
|
||||
|
@ -87,9 +95,9 @@ class ViewsModerationStateFilterTest extends ViewTestBase {
|
|||
$this->drupalPostForm("admin/structure/views/nojs/handler/$view_id/default/filter/moderation_state", $edit, 'Apply');
|
||||
$this->drupalPostForm("admin/structure/views/view/$view_id", [], 'Save');
|
||||
|
||||
$view = Views::getView($view_id);
|
||||
$view = $this->loadViewUnchanged($view_id);
|
||||
$this->assertWorkflowDependencies(['editorial'], $view);
|
||||
$this->assertTrue($view->storage->status());
|
||||
$this->assertTrue($view->status());
|
||||
|
||||
// Create another workflow and repeat the checks above.
|
||||
$this->drupalPostForm('admin/config/workflow/workflows/add', [
|
||||
|
@ -109,35 +117,44 @@ class ViewsModerationStateFilterTest extends ViewTestBase {
|
|||
$this->drupalPostForm("admin/structure/views/nojs/handler/$view_id/default/filter/moderation_state", $edit, 'Apply');
|
||||
$this->drupalPostForm("admin/structure/views/view/$view_id", [], 'Save');
|
||||
|
||||
$view = Views::getView($view_id);
|
||||
$view = $this->loadViewUnchanged($view_id);
|
||||
$this->assertWorkflowDependencies(['editorial', 'translation'], $view);
|
||||
$this->assertTrue(isset($view->storage->getDisplay('default')['display_options']['filters']['moderation_state']));
|
||||
$this->assertTrue($view->storage->status());
|
||||
$this->assertTrue(isset($view->getDisplay('default')['display_options']['filters']['moderation_state']));
|
||||
$this->assertTrue($view->status());
|
||||
|
||||
// Remove the 'Translation' workflow.
|
||||
$this->drupalPostForm('admin/config/workflow/workflows/manage/translation/delete', [], 'Delete');
|
||||
|
||||
// Check that the view has been disabled, the filter has been deleted, the
|
||||
// view can be saved and there are no more config dependencies.
|
||||
$view = Views::getView($view_id);
|
||||
$this->assertFalse($view->storage->status());
|
||||
$this->assertFalse(isset($view->storage->getDisplay('default')['display_options']['filters']['moderation_state']));
|
||||
$view = $this->loadViewUnchanged($view_id);
|
||||
$this->assertFalse($view->status());
|
||||
$this->assertFalse(isset($view->getDisplay('default')['display_options']['filters']['moderation_state']));
|
||||
$this->drupalPostForm("admin/structure/views/view/$view_id", [], 'Save');
|
||||
$this->assertWorkflowDependencies([], $view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a view from the database after it has been modified in a sub-request.
|
||||
*
|
||||
* @param string $view_id
|
||||
* The view ID.
|
||||
*
|
||||
* @return \Drupal\views\ViewEntityInterface
|
||||
* A loaded view, bypassing static caches.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the moderation state filter when the configured workflow is changed.
|
||||
*
|
||||
* @dataProvider providerTestWorkflowChanges
|
||||
*/
|
||||
public function testWorkflowChanges($view_id, $filter_name) {
|
||||
// Update the view and make the default filter not exposed anymore,
|
||||
// otherwise all results will be shown when there are no more moderated
|
||||
// bundles left.
|
||||
$this->drupalPostForm("admin/structure/views/nojs/handler/$view_id/default/filter/moderation_state", [], 'Hide filter');
|
||||
$this->drupalPostForm("admin/structure/views/view/$view_id", [], 'Save');
|
||||
|
||||
public function testWorkflowChanges($view_id) {
|
||||
// First, apply the Editorial workflow to both of our content types.
|
||||
$this->drupalPostForm('admin/config/workflow/workflows/manage/editorial/type/node', [
|
||||
'bundles[example_a]' => TRUE,
|
||||
|
@ -145,6 +162,12 @@ class ViewsModerationStateFilterTest extends ViewTestBase {
|
|||
], 'Save');
|
||||
\Drupal::service('entity_type.bundle.info')->clearCachedBundles();
|
||||
|
||||
// Update the view and make the default filter not exposed anymore,
|
||||
// otherwise all results will be shown when there are no more moderated
|
||||
// bundles left.
|
||||
$this->drupalPostForm("admin/structure/views/nojs/handler/$view_id/default/filter/moderation_state", [], 'Hide filter');
|
||||
$this->drupalPostForm("admin/structure/views/view/$view_id", [], 'Save');
|
||||
|
||||
// Add a few nodes in various moderation states.
|
||||
$this->createNode(['type' => 'example_a', 'moderation_state' => 'published']);
|
||||
$this->createNode(['type' => 'example_b', 'moderation_state' => 'published']);
|
||||
|
@ -158,9 +181,8 @@ class ViewsModerationStateFilterTest extends ViewTestBase {
|
|||
|
||||
// Check that only the archived nodes from both bundles are displayed by the
|
||||
// view.
|
||||
$view = Views::getView($view_id);
|
||||
$this->executeView($view);
|
||||
$this->assertIdenticalResultset($view, [['nid' => $archived_node_a->id()], ['nid' => $archived_node_b->id()]], ['nid' => 'nid']);
|
||||
$view = $this->loadViewUnchanged($view_id);
|
||||
$this->executeAndAssertIdenticalResultset($view, [['nid' => $archived_node_a->id()], ['nid' => $archived_node_b->id()]], ['nid' => 'nid']);
|
||||
|
||||
// Remove the Editorial workflow from one of the bundles.
|
||||
$this->drupalPostForm('admin/config/workflow/workflows/manage/editorial/type/node', [
|
||||
|
@ -169,9 +191,8 @@ class ViewsModerationStateFilterTest extends ViewTestBase {
|
|||
], 'Save');
|
||||
\Drupal::service('entity_type.bundle.info')->clearCachedBundles();
|
||||
|
||||
$view = Views::getView($view_id);
|
||||
$this->executeView($view);
|
||||
$this->assertIdenticalResultset($view, [['nid' => $archived_node_a->id()]], ['nid' => 'nid']);
|
||||
$view = $this->loadViewUnchanged($view_id);
|
||||
$this->executeAndAssertIdenticalResultset($view, [['nid' => $archived_node_a->id()]], ['nid' => 'nid']);
|
||||
|
||||
// Check that the view can still be edited and saved without any
|
||||
// intervention.
|
||||
|
@ -184,16 +205,31 @@ class ViewsModerationStateFilterTest extends ViewTestBase {
|
|||
], 'Save');
|
||||
\Drupal::service('entity_type.bundle.info')->clearCachedBundles();
|
||||
|
||||
$view = Views::getView($view_id);
|
||||
$this->executeView($view);
|
||||
|
||||
// Check that the view doesn't return any result.
|
||||
$this->assertEmpty($view->result);
|
||||
$view = $this->loadViewUnchanged($view_id);
|
||||
$this->executeAndAssertIdenticalResultset($view, [], []);
|
||||
|
||||
// Check that the view can not be edited without any intervention anymore
|
||||
// because the user needs to fix the filter.
|
||||
// Check that the view contains a broken filter, since the moderation_state
|
||||
// field was removed from the entity type.
|
||||
$this->drupalPostForm("admin/structure/views/view/$view_id", [], 'Save');
|
||||
$this->assertSession()->pageTextContains("No valid values found on filter: $filter_name.");
|
||||
$this->assertSession()->pageTextContains("Broken/missing handler");
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a view and asssert the expected results.
|
||||
*
|
||||
* @param \Drupal\views\ViewEntityInterface $view_entity
|
||||
* A view configuration entity.
|
||||
* @param array $expected
|
||||
* An expected result set.
|
||||
* @param array $column_map
|
||||
* An associative array mapping the columns of the result set from the view
|
||||
* (as keys) and the expected result set (as values).
|
||||
*/
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -206,11 +242,9 @@ class ViewsModerationStateFilterTest extends ViewTestBase {
|
|||
return [
|
||||
'view on base table, filter on base table' => [
|
||||
'test_content_moderation_state_filter_base_table',
|
||||
'Content: Moderation state',
|
||||
],
|
||||
'view on base table, filter on revision table' => [
|
||||
'test_content_moderation_state_filter_base_table_filter_on_revision',
|
||||
'Content revision: Moderation state',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
@ -293,10 +327,10 @@ class ViewsModerationStateFilterTest extends ViewTestBase {
|
|||
*
|
||||
* @param string[] $workflow_ids
|
||||
* An array of workflow IDs to check.
|
||||
* @param \Drupal\views\ViewExecutable $view
|
||||
* An executable View object.
|
||||
* @param \Drupal\views\ViewEntityInterface $view
|
||||
* A view configuration object.
|
||||
*/
|
||||
protected function assertWorkflowDependencies(array $workflow_ids, ViewExecutable $view) {
|
||||
protected function assertWorkflowDependencies(array $workflow_ids, ViewEntityInterface $view) {
|
||||
$dependencies = $view->getDependencies();
|
||||
|
||||
$expected = [];
|
||||
|
|
|
@ -161,6 +161,7 @@ class EntityStateChangeValidationTest extends KernelTestBase {
|
|||
$workflow->save();
|
||||
|
||||
// Validate the invalid state.
|
||||
$node = Node::load($node->id());
|
||||
$node->moderation_state->value = 'invalid_state';
|
||||
$violations = $node->validate();
|
||||
$this->assertCount(1, $violations);
|
||||
|
|
|
@ -4,7 +4,9 @@ namespace Drupal\Tests\content_moderation\Kernel;
|
|||
|
||||
use Drupal\content_moderation\Entity\Handler\ModerationHandler;
|
||||
use Drupal\content_moderation\EntityTypeInfo;
|
||||
use Drupal\entity_test\Entity\EntityTestBundle;
|
||||
use Drupal\KernelTests\KernelTestBase;
|
||||
use Drupal\Tests\content_moderation\Traits\ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\content_moderation\EntityTypeInfo
|
||||
|
@ -13,6 +15,8 @@ use Drupal\KernelTests\KernelTestBase;
|
|||
*/
|
||||
class EntityTypeInfoTest extends KernelTestBase {
|
||||
|
||||
use ContentModerationTestTrait;
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
|
@ -43,8 +47,11 @@ class EntityTypeInfoTest extends KernelTestBase {
|
|||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->entityTypeInfo = $this->container->get('class_resolver')->getInstanceFromDefinition(EntityTypeInfo::class);
|
||||
$this->entityTypeManager = $this->container->get('entity_type.manager');
|
||||
|
||||
$this->installConfig(['content_moderation']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,6 +61,7 @@ class EntityTypeInfoTest extends KernelTestBase {
|
|||
$definition = $this->entityTypeManager->getDefinition('entity_test');
|
||||
$definition->setHandlerClass('moderation', ModerationHandler::class);
|
||||
|
||||
$this->enableModeration('entity_test', 'entity_test');
|
||||
$base_fields = $this->entityTypeInfo->entityBaseFieldInfo($definition);
|
||||
|
||||
$this->assertFalse($base_fields['moderation_state']->isReadOnly());
|
||||
|
@ -91,4 +99,34 @@ class EntityTypeInfoTest extends KernelTestBase {
|
|||
return $tests;
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::entityBaseFieldInfo
|
||||
*/
|
||||
public function testBaseFieldOnlyAddedToModeratedEntityTypes() {
|
||||
$definition = $this->entityTypeManager->getDefinition('entity_test_with_bundle');
|
||||
|
||||
EntityTestBundle::create([
|
||||
'id' => 'moderated',
|
||||
])->save();
|
||||
EntityTestBundle::create([
|
||||
'id' => 'unmoderated',
|
||||
])->save();
|
||||
|
||||
$base_fields = $this->entityTypeInfo->entityBaseFieldInfo($definition);
|
||||
$this->assertFalse(isset($base_fields['moderation_state']));
|
||||
|
||||
$this->enableModeration('entity_test_with_bundle', 'moderated');
|
||||
$base_fields = $this->entityTypeInfo->entityBaseFieldInfo($definition);
|
||||
$this->assertTrue(isset($base_fields['moderation_state']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add moderation to an entity type and bundle.
|
||||
*/
|
||||
protected function enableModeration($entity_type_id, $bundle) {
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle($entity_type_id, $bundle);
|
||||
$workflow->save();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ class ViewsDataIntegrationTest extends ViewsKernelTestBase {
|
|||
$this->installEntitySchema('user');
|
||||
$this->installEntitySchema('content_moderation_state');
|
||||
$this->installSchema('node', 'node_access');
|
||||
$this->installConfig('content_moderation_test_views');
|
||||
$this->installConfig('content_moderation');
|
||||
|
||||
$node_type = NodeType::create([
|
||||
|
@ -50,6 +49,8 @@ class ViewsDataIntegrationTest extends ViewsKernelTestBase {
|
|||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'page');
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_mulrevpub', 'entity_test_mulrevpub');
|
||||
$workflow->save();
|
||||
|
||||
$this->installConfig('content_moderation_test_views');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,7 +47,6 @@ class ViewsModerationStateFilterTest extends ViewsKernelTestBase {
|
|||
$this->installEntitySchema('content_moderation_state');
|
||||
$this->installEntitySchema('entity_test_no_bundle');
|
||||
$this->installSchema('node', 'node_access');
|
||||
$this->installConfig('content_moderation_test_views');
|
||||
$this->installConfig('content_moderation');
|
||||
|
||||
$node_type = NodeType::create([
|
||||
|
@ -65,6 +64,14 @@ class ViewsModerationStateFilterTest extends ViewsKernelTestBase {
|
|||
]);
|
||||
$node_type->save();
|
||||
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->save();
|
||||
|
||||
// Install the test views after moderation has been enabled on the example
|
||||
// bundle, so the moderation_state field exists.
|
||||
$this->installConfig('content_moderation_test_views');
|
||||
|
||||
ConfigurableLanguage::createFromLangcode('fr')->save();
|
||||
}
|
||||
|
||||
|
@ -72,7 +79,7 @@ class ViewsModerationStateFilterTest extends ViewsKernelTestBase {
|
|||
* Tests the content moderation state filter.
|
||||
*/
|
||||
public function testStateFilterViewsRelationship() {
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->getTypePlugin()->addState('translated_draft', 'Bar');
|
||||
$configuration = $workflow->getTypePlugin()->getConfiguration();
|
||||
|
@ -159,7 +166,7 @@ class ViewsModerationStateFilterTest extends ViewsKernelTestBase {
|
|||
* Test the moderation filter with a non-translatable entity type.
|
||||
*/
|
||||
public function testNonTranslatableEntityType() {
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('entity_test_no_bundle', 'entity_test_no_bundle');
|
||||
$workflow->save();
|
||||
|
||||
|
@ -181,11 +188,13 @@ class ViewsModerationStateFilterTest extends ViewsKernelTestBase {
|
|||
*/
|
||||
public function testStateFilterStatesList() {
|
||||
// By default a view of nodes will not have states to filter.
|
||||
$workflow = Workflow::load('editorial');
|
||||
$workflow->getTypePlugin()->removeEntityTypeAndBundle('node', 'example');
|
||||
$workflow->save();
|
||||
$this->assertPluginStates([]);
|
||||
|
||||
// Adding a content type to the editorial workflow will enable all of the
|
||||
// editorial states.
|
||||
$workflow = $this->createEditorialWorkflow();
|
||||
$workflow->getTypePlugin()->addEntityTypeAndBundle('node', 'example');
|
||||
$workflow->save();
|
||||
$this->assertPluginStates([
|
||||
|
|
|
@ -7,6 +7,7 @@ use Drupal\Core\Entity\ContentEntityInterface;
|
|||
use Drupal\Core\Entity\ContentEntityType;
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
|
||||
use Drupal\Core\Entity\EntityTypeInterface;
|
||||
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\content_moderation\ModerationInformation;
|
||||
|
@ -58,10 +59,27 @@ class ModerationInformationTest extends UnitTestCase {
|
|||
}
|
||||
$bundle_info = $this->prophesize(EntityTypeBundleInfoInterface::class);
|
||||
$bundle_info->getBundleInfo("test_entity_type")->willReturn([$bundle => $bundle_info_array]);
|
||||
$bundle_info->getBundleInfo("unmoderated_test_type")->willReturn([$bundle => []]);
|
||||
|
||||
return $bundle_info->reveal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::isModeratedEntityType
|
||||
*/
|
||||
public function testIsModeratedEntityType() {
|
||||
$moderation_information = new ModerationInformation($this->getEntityTypeManager(), $this->setupModerationBundleInfo('test_bundle', 'workflow'));
|
||||
|
||||
$moderated_entity_type = $this->prophesize(EntityTypeInterface::class);
|
||||
$moderated_entity_type->id()->willReturn('test_entity_type');
|
||||
|
||||
$unmoderated_entity_type = $this->prophesize(EntityTypeInterface::class);
|
||||
$unmoderated_entity_type->id()->willReturn('unmoderated_test_type');
|
||||
|
||||
$this->assertTrue($moderation_information->isModeratedEntityType($moderated_entity_type->reveal()));
|
||||
$this->assertFalse($moderation_information->isModeratedEntityType($unmoderated_entity_type->reveal()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerWorkflow
|
||||
* @covers ::isModeratedEntity
|
||||
|
|
|
@ -7,6 +7,7 @@ dependencies:
|
|||
- field.field.node.article.field_tags
|
||||
- image.style.thumbnail
|
||||
- node.type.article
|
||||
- workflows.workflow.editorial
|
||||
module:
|
||||
- content_moderation
|
||||
- image
|
||||
|
|
|
@ -4,6 +4,7 @@ dependencies:
|
|||
config:
|
||||
- field.field.node.page.body
|
||||
- node.type.page
|
||||
- workflows.workflow.editorial
|
||||
module:
|
||||
- content_moderation
|
||||
- path
|
||||
|
|
|
@ -14,6 +14,7 @@ dependencies:
|
|||
- field.field.node.recipe.field_tags
|
||||
- image.style.thumbnail
|
||||
- node.type.recipe
|
||||
- workflows.workflow.editorial
|
||||
module:
|
||||
- content_moderation
|
||||
- image
|
||||
|
|
Loading…
Reference in New Issue