BlockContentTypeTest.php

Same filename in this branch
  1. 8.9.x core/modules/jsonapi/tests/src/Functional/BlockContentTypeTest.php
Same filename and directory in other branches
  1. 9 core/modules/jsonapi/tests/src/Functional/BlockContentTypeTest.php
  2. 9 core/modules/block_content/tests/src/Functional/BlockContentTypeTest.php
  3. 10 core/modules/jsonapi/tests/src/Functional/BlockContentTypeTest.php
  4. 10 core/modules/block_content/tests/src/Functional/BlockContentTypeTest.php
  5. 11.x core/modules/jsonapi/tests/src/Functional/BlockContentTypeTest.php
  6. 11.x core/modules/block_content/tests/src/Functional/BlockContentTypeTest.php

Namespace

Drupal\Tests\block_content\Functional

File

core/modules/block_content/tests/src/Functional/BlockContentTypeTest.php

View source
<?php

namespace Drupal\Tests\block_content\Functional;

use Drupal\block_content\Entity\BlockContentType;
use Drupal\Component\Utility\Html;
use Drupal\Core\Url;
use Drupal\Tests\system\Functional\Menu\AssertBreadcrumbTrait;

/**
 * Ensures that custom block type functions work correctly.
 *
 * @group block_content
 */
class BlockContentTypeTest extends BlockContentTestBase {
    use AssertBreadcrumbTrait;
    
    /**
     * Modules to enable.
     *
     * @var array
     */
    public static $modules = [
        'field_ui',
    ];
    
    /**
     * {@inheritdoc}
     */
    protected $defaultTheme = 'classy';
    
    /**
     * Permissions to grant admin user.
     *
     * @var array
     */
    protected $permissions = [
        'administer blocks',
        'administer block_content fields',
    ];
    
    /**
     * Whether or not to create an initial block type.
     *
     * @var bool
     */
    protected $autoCreateBasicBlockType = FALSE;
    protected function setUp() {
        parent::setUp();
        $this->drupalPlaceBlock('page_title_block');
    }
    
    /**
     * Tests creating a block type programmatically and via a form.
     */
    public function testBlockContentTypeCreation() {
        // Log in a test user.
        $this->drupalLogin($this->adminUser);
        // Test the page with no block-types.
        $this->drupalGet('block/add');
        $this->assertSession()
            ->statusCodeEquals(200);
        $this->assertText('You have not created any block types yet');
        $this->clickLink('block type creation page');
        // Create a block type via the user interface.
        $edit = [
            'id' => 'foo',
            'label' => 'title for foo',
        ];
        $this->drupalPostForm(NULL, $edit, t('Save'));
        $block_type = BlockContentType::load('foo');
        $this->assertInstanceOf(BlockContentType::class, $block_type);
        $field_definitions = \Drupal::service('entity_field.manager')->getFieldDefinitions('block_content', 'foo');
        $this->assertTrue(isset($field_definitions['body']), 'Body field created when using the UI to create block content types.');
        // Check that the block type was created in site default language.
        $default_langcode = \Drupal::languageManager()->getDefaultLanguage()
            ->getId();
        $this->assertEqual($block_type->language()
            ->getId(), $default_langcode);
        // Create block types programmatically.
        $this->createBlockContentType('basic', TRUE);
        $field_definitions = \Drupal::service('entity_field.manager')->getFieldDefinitions('block_content', 'basic');
        $this->assertTrue(isset($field_definitions['body']), "Body field for 'basic' block type created when using the testing API to create block content types.");
        $this->createBlockContentType('other');
        $field_definitions = \Drupal::service('entity_field.manager')->getFieldDefinitions('block_content', 'other');
        $this->assertFalse(isset($field_definitions['body']), "Body field for 'other' block type not created when using the testing API to create block content types.");
        $block_type = BlockContentType::load('other');
        $this->assertInstanceOf(BlockContentType::class, $block_type);
        $this->drupalGet('block/add/' . $block_type->id());
        $this->assertSession()
            ->statusCodeEquals(200);
    }
    
    /**
     * Tests editing a block type using the UI.
     */
    public function testBlockContentTypeEditing() {
        $this->drupalPlaceBlock('system_breadcrumb_block');
        // Now create an initial block-type.
        $this->createBlockContentType('basic', TRUE);
        $this->drupalLogin($this->adminUser);
        // We need two block types to prevent /block/add redirecting.
        $this->createBlockContentType('other');
        $field_definitions = \Drupal::service('entity_field.manager')->getFieldDefinitions('block_content', 'other');
        $this->assertFalse(isset($field_definitions['body']), 'Body field was not created when using the API to create block content types.');
        // Verify that title and body fields are displayed.
        $this->drupalGet('block/add/basic');
        $this->assertRaw('Block description', 'Block info field was found.');
        $this->assertNotEmpty($this->cssSelect('#edit-body-0-value'), 'Body field was found.');
        // Change the block type name.
        $edit = [
            'label' => 'Bar',
        ];
        $this->drupalGet('admin/structure/block/block-content/manage/basic');
        $this->assertTitle('Edit basic custom block type | Drupal');
        $this->drupalPostForm(NULL, $edit, t('Save'));
        $front_page_path = Url::fromRoute('<front>')->toString();
        $this->assertBreadcrumb('admin/structure/block/block-content/manage/basic/fields', [
            $front_page_path => 'Home',
            'admin/structure/block' => 'Block layout',
            'admin/structure/block/block-content' => 'Custom block library',
            'admin/structure/block/block-content/manage/basic' => 'Edit Bar',
        ]);
        \Drupal::service('entity_field.manager')->clearCachedFieldDefinitions();
        $this->drupalGet('block/add');
        $this->assertRaw('Bar', 'New name was displayed.');
        $this->clickLink('Bar');
        $this->assertUrl(Url::fromRoute('block_content.add_form', [
            'block_content_type' => 'basic',
        ], [
            'absolute' => TRUE,
        ])->toString(), [], 'Original machine name was used in URL.');
        // Remove the body field.
        $this->drupalPostForm('admin/structure/block/block-content/manage/basic/fields/block_content.basic.body/delete', [], t('Delete'));
        // Resave the settings for this type.
        $this->drupalPostForm('admin/structure/block/block-content/manage/basic', [], t('Save'));
        // Check that the body field doesn't exist.
        $this->drupalGet('block/add/basic');
        $this->assertEmpty($this->cssSelect('#edit-body-0-value'), 'Body field was not found.');
    }
    
    /**
     * Tests deleting a block type that still has content.
     */
    public function testBlockContentTypeDeletion() {
        // Now create an initial block-type.
        $this->createBlockContentType('basic', TRUE);
        // Create a block type programmatically.
        $type = $this->createBlockContentType('foo');
        $this->drupalLogin($this->adminUser);
        // Add a new block of this type.
        $block = $this->createBlockContent(FALSE, 'foo');
        // Attempt to delete the block type, which should not be allowed.
        $this->drupalGet('admin/structure/block/block-content/manage/' . $type->id() . '/delete');
        $this->assertRaw(t('%label is used by 1 custom block on your site. You can not remove this block type until you have removed all of the %label blocks.', [
            '%label' => $type->label(),
        ]), 'The block type will not be deleted until all blocks of that type are removed.');
        $this->assertNoText(t('This action cannot be undone.'), 'The block type deletion confirmation form is not available.');
        // Delete the block.
        $block->delete();
        // Attempt to delete the block type, which should now be allowed.
        $this->drupalGet('admin/structure/block/block-content/manage/' . $type->id() . '/delete');
        $this->assertRaw(t('Are you sure you want to delete the custom block type %type?', [
            '%type' => $type->id(),
        ]), 'The block type is available for deletion.');
        $this->assertText(t('This action cannot be undone.'), 'The custom block type deletion confirmation form is available.');
    }
    
    /**
     * Tests that redirects work as expected when multiple block types exist.
     */
    public function testsBlockContentAddTypes() {
        // Now create an initial block-type.
        $this->createBlockContentType('basic', TRUE);
        $this->drupalLogin($this->adminUser);
        // Create two block types programmatically.
        $type = $this->createBlockContentType('foo');
        $type = $this->createBlockContentType('bar');
        // Get the custom block storage.
        $storage = $this->container
            ->get('entity_type.manager')
            ->getStorage('block_content');
        // Install all themes.
        \Drupal::service('theme_installer')->install([
            'bartik',
            'seven',
            'stark',
        ]);
        $theme_settings = $this->config('system.theme');
        foreach ([
            'bartik',
            'seven',
            'stark',
        ] as $default_theme) {
            // Change the default theme.
            $theme_settings->set('default', $default_theme)
                ->save();
            $this->drupalPlaceBlock('local_actions_block');
            \Drupal::service('router.builder')->rebuild();
            // For each installed theme, go to its block page and test the redirects.
            foreach ([
                'bartik',
                'seven',
                'stark',
            ] as $theme) {
                // Test that adding a block from the 'place blocks' form sends you to the
                // block configure form.
                $path = $theme == $default_theme ? 'admin/structure/block' : "admin/structure/block/list/{$theme}";
                $this->drupalGet($path);
                $this->clickLink('Place block');
                $this->clickLink(t('Add custom block'));
                // The seven theme has markup inside the link, we cannot use clickLink().
                if ($default_theme == 'seven') {
                    $options = $theme != $default_theme ? [
                        'query' => [
                            'theme' => $theme,
                        ],
                    ] : [];
                    $this->assertLinkByHref(Url::fromRoute('block_content.add_form', [
                        'block_content_type' => 'foo',
                    ], $options)->toString());
                    $this->drupalGet('block/add/foo', $options);
                }
                else {
                    $this->clickLink('foo');
                }
                // Create a new block.
                $edit = [
                    'info[0][value]' => $this->randomMachineName(8),
                ];
                $this->drupalPostForm(NULL, $edit, t('Save'));
                $blocks = $storage->loadByProperties([
                    'info' => $edit['info[0][value]'],
                ]);
                if (!empty($blocks)) {
                    $block = reset($blocks);
                    $this->assertUrl(Url::fromRoute('block.admin_add', [
                        'plugin_id' => 'block_content:' . $block->uuid(),
                        'theme' => $theme,
                    ], [
                        'absolute' => TRUE,
                    ])
                        ->toString());
                    $this->drupalPostForm(NULL, [
                        'region' => 'content',
                    ], t('Save block'));
                    $this->assertUrl(Url::fromRoute('block.admin_display_theme', [
                        'theme' => $theme,
                    ], [
                        'absolute' => TRUE,
                        'query' => [
                            'block-placement' => Html::getClass($edit['info[0][value]']),
                        ],
                    ])->toString());
                }
                else {
                    $this->fail('Could not load created block.');
                }
            }
        }
        // Test that adding a block from the 'custom blocks list' doesn't send you
        // to the block configure form.
        $this->drupalGet('admin/structure/block/block-content');
        $this->clickLink(t('Add custom block'));
        $this->clickLink('foo');
        $edit = [
            'info[0][value]' => $this->randomMachineName(8),
        ];
        $this->drupalPostForm(NULL, $edit, t('Save'));
        $blocks = $storage->loadByProperties([
            'info' => $edit['info[0][value]'],
        ]);
        if (!empty($blocks)) {
            $this->assertUrl(Url::fromRoute('entity.block_content.collection', [], [
                'absolute' => TRUE,
            ])->toString());
        }
        else {
            $this->fail('Could not load created block.');
        }
    }

}

Classes

Title Deprecated Summary
BlockContentTypeTest Ensures that custom block type functions work correctly.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.