FieldNoteItemTest.php

Same filename in other branches
  1. 4.0.x modules/field_permission_example/tests/src/Kernel/FieldNoteItemTest.php

Namespace

Drupal\Tests\field_permission_example\Kernel

File

modules/field_permission_example/tests/src/Kernel/FieldNoteItemTest.php

View source
<?php

namespace Drupal\Tests\field_permission_example\Kernel;

use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FieldItemInterface;
use Drupal\Tests\field\Kernel\FieldKernelTestBase;
use Drupal\Tests\user\Traits\UserCreationTrait;

/**
 * Tests our sticky-note field type.
 *
 * This class is based off the tests used in Drupal core for field plugins,
 * since we need to use some of the same convenience methods for testing
 * our custom field type. This base class also brings in the new
 * PHPUnit-based kernel test system that replaces the older Simpletest-
 * based classes.
 *
 * @see \Drupal\KernelTests\KernelTestBase
 *
 * @group field_permission_example
 * @group examples
 */
class FieldNoteItemTest extends FieldKernelTestBase {
    use UserCreationTrait;
    
    /**
     * We add the additional modules we need loaded here.
     *
     * The test runner will merge the $modules lists from this class, the class
     * it extends, and so on up the class hierarchy. So, it is not necessary to
     * include modules in your list that a parent class has already declared.
     *
     * @var array
     */
    protected static $modules = [
        'field_permission_example',
    ];
    
    /**
     * {@inheritdoc}
     *
     * This sets up the entity_test and user types to use our example
     * field plugins.
     */
    protected function setUp() : void {
        parent::setUp();
        $type_manager = $this->container
            ->get('entity_type.manager');
        // Set up our entity_type and user type for our new field:
        $type_manager->getStorage('field_storage_config')
            ->create([
            'field_name' => 'field_fieldnote',
            'entity_type' => 'entity_test',
            'type' => 'field_permission_example_fieldnote',
        ])
            ->save();
        $type_manager->getStorage('field_config')
            ->create([
            'entity_type' => 'entity_test',
            'field_name' => 'field_fieldnote',
            'bundle' => 'entity_test',
        ])
            ->save();
        // Create a form display for the default form mode, and
        // add our field type.
        $type_manager->getStorage('entity_form_display')
            ->create([
            'targetEntityType' => 'entity_test',
            'bundle' => 'entity_test',
            'mode' => 'default',
            'status' => TRUE,
        ])
            ->setComponent('field_fieldnote', [
            'type' => 'field_permission_example_widget',
        ])
            ->save();
        // Now do this for the user type.
        $type_manager->getStorage('field_storage_config')
            ->create([
            'field_name' => 'user_fieldnote',
            'entity_type' => 'user',
            'type' => 'field_permission_example_fieldnote',
        ])
            ->save();
        $type_manager->getStorage('field_config')
            ->create([
            'entity_type' => 'user',
            'field_name' => 'user_fieldnote',
            'bundle' => 'user',
        ])
            ->save();
        // Fetch a form display for a user. This may already exist, so check as
        // Core does.
        // @see https://api.drupal.org/api/drupal/core%21includes%21entity.inc/function/entity_get_form_display/8
        $entity_form_display = $type_manager->getStorage('entity_form_display')
            ->load('user.user.default');
        if (empty($entity_form_display)) {
            $entity_form_display = $type_manager->getStorage('entity_form_display')
                ->create([
                'targetEntityType' => 'user',
                'bundle' => 'user',
                'mode' => 'default',
                'status' => TRUE,
            ]);
        }
        // And add our fancy field to that display:
        $entity_form_display->setComponent('field_fieldnote', [
            'type' => 'field_permission_example_widget',
        ])
            ->save();
    }
    
    /**
     * Test entity fields of the field_permission_example_fieldnote field type.
     */
    public function testFieldNoteItem() {
        // Verify entity creation.
        $type_manager = $this->container
            ->get('entity_type.manager');
        $entity = $type_manager->getStorage('entity_test')
            ->create([]);
        $value = 'This is an epic entity';
        $entity->field_fieldnote = $value;
        $entity->name->value = $this->randomMachineName();
        $entity->save();
        // Verify entity has been created properly.
        $id = $entity->id();
        $entity = $type_manager->getStorage('entity_test')
            ->load($id);
        $this->assertTrue($entity->field_fieldnote instanceof FieldItemListInterface, 'Field implements interface.');
        $this->assertTrue($entity->field_fieldnote[0] instanceof FieldItemInterface, 'Field item implements interface.');
        $this->assertEquals($entity->field_fieldnote->value, $value);
        $this->assertEquals($entity->field_fieldnote[0]->value, $value);
        // Verify changing the field's value.
        $new_value = $this->randomMachineName();
        $entity->field_fieldnote->value = $new_value;
        $this->assertEquals($entity->field_fieldnote->value, $new_value);
        // Read changed entity and assert changed values.
        $entity->save();
        $entity = $type_manager->getStorage('entity_test')
            ->load($id);
        $this->assertEquals($entity->field_fieldnote->value, $new_value);
        // Test sample item generation.
        $entity = $type_manager->getStorage('entity_test')
            ->create([]);
        $entity->field_fieldnote
            ->generateSampleItems();
        $this->entityValidateAndSave($entity);
    }
    
    /**
     * Test multiple access scenarios for the fieldnote field.
     */
    public function testFieldNoteAccess() {
        // Let's set up some scenarios.
        $scenarios = [
            'admin_type' => [
                'perms' => [
                    'administer the fieldnote field',
                ],
                'can_view_any' => TRUE,
                'can_edit_any' => TRUE,
                'can_view_own' => TRUE,
                'can_edit_own' => TRUE,
            ],
            'low_access' => [
                'perms' => [
                    'view test entity',
                ],
                'can_view_any' => FALSE,
                'can_edit_any' => FALSE,
                'can_view_own' => FALSE,
                'can_edit_own' => FALSE,
            ],
            'view_any' => [
                'perms' => [
                    'view test entity',
                    'view any fieldnote',
                ],
                'can_view_any' => TRUE,
                'can_edit_any' => FALSE,
                'can_view_own' => FALSE,
                'can_edit_own' => FALSE,
            ],
            'edit_any' => [
                'perms' => [
                    'view test entity',
                    'view any fieldnote',
                    'edit any fieldnote',
                ],
                'can_view_any' => TRUE,
                'can_edit_any' => TRUE,
                'can_view_own' => FALSE,
                'can_edit_own' => FALSE,
            ],
            'view_own' => [
                'perms' => [
                    'view test entity',
                    'view own fieldnote',
                ],
                'can_view_any' => FALSE,
                'can_edit_any' => FALSE,
                'can_view_own' => TRUE,
                'can_edit_own' => FALSE,
            ],
            'edit_own' => [
                'perms' => [
                    'view test entity',
                    'view own fieldnote',
                    'edit own fieldnote',
                ],
                'can_view_any' => FALSE,
                'can_edit_any' => FALSE,
                'can_view_own' => TRUE,
                'can_edit_own' => TRUE,
            ],
        ];
        $value = 'This is an epic entity';
        // We also need to test users as an entity to attach to.  They work
        // a little differently than most content entity types:
        $arbitrary_user = $this->createUser([], 'Some User');
        $arbitrary_user->user_fieldnote = $value;
        $arbitrary_user->save();
        $storage = $this->container
            ->get('entity_type.manager')
            ->getStorage('entity_test');
        foreach ($scenarios as $name => $scenario) {
            $test_user = $this->createUser($scenario['perms'], $name);
            $entity = $storage->create([
                'entity_test',
            ]);
            $entity->field_fieldnote = $value;
            $entity->name->value = $this->randomMachineName();
            $entity->save();
            foreach ([
                'can_view_any',
                'can_edit_any',
            ] as $op) {
                $this->doAccessAssertion($entity, 'field_fieldnote', $test_user, $name, $op, $scenario[$op]);
                $this->doAccessAssertion($arbitrary_user, 'user_fieldnote', $test_user, $name, $op, $scenario[$op]);
            }
            if ($scenario['can_view_own'] or $scenario['can_edit_own']) {
                $entity->user_id = $test_user;
                $entity->save();
                $test_user->user_fieldnote = $value;
                $test_user->save();
                foreach ([
                    'can_view_own',
                    'can_edit_own',
                ] as $op) {
                    $this->doAccessAssertion($entity, 'field_fieldnote', $test_user, $name, $op, $scenario[$op]);
                    $this->doAccessAssertion($test_user, 'user_fieldnote', $test_user, $name, $op, $scenario[$op]);
                }
            }
        }
    }
    
    /**
     * Helper routine to run the assertions.
     */
    protected function doAccessAssertion($entity, $field_name, $account, $name, $op, $expected) {
        $expect_str = $expected ? "CAN" : "CANNOT";
        $assert_str = "{$name} {$expect_str} do {$op} on field {$field_name}";
        $operation = preg_match('/edit/', $op) ? "edit" : "view";
        $result = $entity->{$field_name}
            ->access($operation, $account);
        if ($expected) {
            $this->assertTrue($result, $assert_str);
        }
        else {
            $this->assertFalse($result, $assert_str);
        }
    }

}

Classes

Title Deprecated Summary
FieldNoteItemTest Tests our sticky-note field type.