3 namespace Drupal\block_content\Tests;
5 use Drupal\block_content\Entity\BlockContentType;
6 use Drupal\Component\Utility\Html;
8 use Drupal\system\Tests\Menu\AssertBreadcrumbTrait;
11 * Ensures that custom block type functions work correctly.
13 * @group block_content
15 class BlockContentTypeTest extends BlockContentTestBase {
17 use AssertBreadcrumbTrait;
23 public static $modules = ['field_ui'];
26 * Permissions to grant admin user.
30 protected $permissions = [
32 'administer block_content fields'
36 * Whether or not to create an initial block type.
40 protected $autoCreateBasicBlockType = FALSE;
42 protected function setUp() {
45 $this->drupalPlaceBlock('page_title_block');
49 * Tests creating a block type programmatically and via a form.
51 public function testBlockContentTypeCreation() {
52 // Log in a test user.
53 $this->drupalLogin($this->adminUser);
55 // Test the page with no block-types.
56 $this->drupalGet('block/add');
57 $this->assertResponse(200);
58 $this->assertText('You have not created any block types yet');
59 $this->clickLink('block type creation page');
61 // Create a block type via the user interface.
64 'label' => 'title for foo',
66 $this->drupalPostForm(NULL, $edit, t('Save'));
67 $block_type = BlockContentType::load('foo');
68 $this->assertTrue($block_type, 'The new block type has been created.');
70 $field_definitions = \Drupal::entityManager()->getFieldDefinitions('block_content', 'foo');
71 $this->assertTrue(isset($field_definitions['body']), 'Body field created when using the UI to create block content types.');
73 // Check that the block type was created in site default language.
74 $default_langcode = \Drupal::languageManager()->getDefaultLanguage()->getId();
75 $this->assertEqual($block_type->language()->getId(), $default_langcode);
77 // Create block types programmatically.
78 $this->createBlockContentType('basic', TRUE);
79 $field_definitions = \Drupal::entityManager()->getFieldDefinitions('block_content', 'basic');
80 $this->assertTrue(isset($field_definitions['body']), "Body field for 'basic' block type created when using the testing API to create block content types.");
82 $this->createBlockContentType('other');
83 $field_definitions = \Drupal::entityManager()->getFieldDefinitions('block_content', 'other');
84 $this->assertFalse(isset($field_definitions['body']), "Body field for 'other' block type not created when using the testing API to create block content types.");
86 $block_type = BlockContentType::load('other');
87 $this->assertTrue($block_type, 'The new block type has been created.');
89 $this->drupalGet('block/add/' . $block_type->id());
90 $this->assertResponse(200);
94 * Tests editing a block type using the UI.
96 public function testBlockContentTypeEditing() {
97 $this->drupalPlaceBlock('system_breadcrumb_block');
98 // Now create an initial block-type.
99 $this->createBlockContentType('basic', TRUE);
101 $this->drupalLogin($this->adminUser);
102 // We need two block types to prevent /block/add redirecting.
103 $this->createBlockContentType('other');
105 $field_definitions = \Drupal::entityManager()->getFieldDefinitions('block_content', 'other');
106 $this->assertFalse(isset($field_definitions['body']), 'Body field was not created when using the API to create block content types.');
108 // Verify that title and body fields are displayed.
109 $this->drupalGet('block/add/basic');
110 $this->assertRaw('Block description', 'Block info field was found.');
111 $this->assertRaw('Body', 'Body field was found.');
113 // Change the block type name.
117 $this->drupalGet('admin/structure/block/block-content/manage/basic');
118 $this->assertTitle(format_string('Edit @type custom block type | Drupal', ['@type' => 'basic']));
119 $this->drupalPostForm(NULL, $edit, t('Save'));
120 $front_page_path = Url::fromRoute('<front>')->toString();
121 $this->assertBreadcrumb('admin/structure/block/block-content/manage/basic/fields', [
122 $front_page_path => 'Home',
123 'admin/structure/block' => 'Block layout',
124 'admin/structure/block/block-content' => 'Custom block library',
125 'admin/structure/block/block-content/manage/basic' => 'Bar',
127 \Drupal::entityManager()->clearCachedFieldDefinitions();
129 $this->drupalGet('block/add');
130 $this->assertRaw('Bar', 'New name was displayed.');
131 $this->clickLink('Bar');
132 $this->assertUrl(\Drupal::url('block_content.add_form', ['block_content_type' => 'basic'], ['absolute' => TRUE]), [], 'Original machine name was used in URL.');
134 // Remove the body field.
135 $this->drupalPostForm('admin/structure/block/block-content/manage/basic/fields/block_content.basic.body/delete', [], t('Delete'));
136 // Resave the settings for this type.
137 $this->drupalPostForm('admin/structure/block/block-content/manage/basic', [], t('Save'));
138 // Check that the body field doesn't exist.
139 $this->drupalGet('block/add/basic');
140 $this->assertNoRaw('Body', 'Body field was not found.');
144 * Tests deleting a block type that still has content.
146 public function testBlockContentTypeDeletion() {
147 // Now create an initial block-type.
148 $this->createBlockContentType('basic', TRUE);
150 // Create a block type programmatically.
151 $type = $this->createBlockContentType('foo');
153 $this->drupalLogin($this->adminUser);
155 // Add a new block of this type.
156 $block = $this->createBlockContent(FALSE, 'foo');
157 // Attempt to delete the block type, which should not be allowed.
158 $this->drupalGet('admin/structure/block/block-content/manage/' . $type->id() . '/delete');
160 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()]),
161 'The block type will not be deleted until all blocks of that type are removed.'
163 $this->assertNoText(t('This action cannot be undone.'), 'The block type deletion confirmation form is not available.');
167 // Attempt to delete the block type, which should now be allowed.
168 $this->drupalGet('admin/structure/block/block-content/manage/' . $type->id() . '/delete');
170 t('Are you sure you want to delete the custom block type %type?', ['%type' => $type->id()]),
171 'The block type is available for deletion.'
173 $this->assertText(t('This action cannot be undone.'), 'The custom block type deletion confirmation form is available.');
177 * Tests that redirects work as expected when multiple block types exist.
179 public function testsBlockContentAddTypes() {
180 // Now create an initial block-type.
181 $this->createBlockContentType('basic', TRUE);
183 $this->drupalLogin($this->adminUser);
184 // Create two block types programmatically.
185 $type = $this->createBlockContentType('foo');
186 $type = $this->createBlockContentType('bar');
188 // Get the custom block storage.
189 $storage = $this->container
190 ->get('entity.manager')
191 ->getStorage('block_content');
193 // Install all themes.
194 \Drupal::service('theme_handler')->install(['bartik', 'seven', 'stark']);
195 $theme_settings = $this->config('system.theme');
196 foreach (['bartik', 'seven', 'stark'] as $default_theme) {
197 // Change the default theme.
198 $theme_settings->set('default', $default_theme)->save();
199 \Drupal::service('router.builder')->rebuild();
201 // For each installed theme, go to its block page and test the redirects.
202 foreach (['bartik', 'seven', 'stark'] as $theme) {
203 // Test that adding a block from the 'place blocks' form sends you to the
204 // block configure form.
205 $path = $theme == $default_theme ? 'admin/structure/block' : "admin/structure/block/list/$theme";
206 $this->drupalGet($path);
207 $this->clickLinkPartialName('Place block');
208 $this->clickLink(t('Add custom block'));
209 // The seven theme has markup inside the link, we cannot use clickLink().
210 if ($default_theme == 'seven') {
211 $options = $theme != $default_theme ? ['query' => ['theme' => $theme]] : [];
212 $this->assertLinkByHref(\Drupal::url('block_content.add_form', ['block_content_type' => 'foo'], $options));
213 $this->drupalGet('block/add/foo', $options);
216 $this->clickLink('foo');
218 // Create a new block.
219 $edit = ['info[0][value]' => $this->randomMachineName(8)];
220 $this->drupalPostForm(NULL, $edit, t('Save'));
221 $blocks = $storage->loadByProperties(['info' => $edit['info[0][value]']]);
222 if (!empty($blocks)) {
223 $block = reset($blocks);
224 $this->assertUrl(\Drupal::url('block.admin_add', ['plugin_id' => 'block_content:' . $block->uuid(), 'theme' => $theme], ['absolute' => TRUE]));
225 $this->drupalPostForm(NULL, ['region' => 'content'], t('Save block'));
226 $this->assertUrl(\Drupal::url('block.admin_display_theme', ['theme' => $theme], ['absolute' => TRUE, 'query' => ['block-placement' => Html::getClass($edit['info[0][value]'])]]));
229 $this->fail('Could not load created block.');
234 // Test that adding a block from the 'custom blocks list' doesn't send you
235 // to the block configure form.
236 $this->drupalGet('admin/structure/block/block-content');
237 $this->clickLink(t('Add custom block'));
238 $this->clickLink('foo');
239 $edit = ['info[0][value]' => $this->randomMachineName(8)];
240 $this->drupalPostForm(NULL, $edit, t('Save'));
241 $blocks = $storage->loadByProperties(['info' => $edit['info[0][value]']]);
242 if (!empty($blocks)) {
243 $this->assertUrl(\Drupal::url('entity.block_content.collection', [], ['absolute' => TRUE]));
246 $this->fail('Could not load created block.');