Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / modules / block_content / tests / src / Functional / BlockContentCreationTest.php
1 <?php
2
3 namespace Drupal\Tests\block_content\Functional;
4
5 use Drupal\block_content\Entity\BlockContent;
6 use Drupal\Core\Database\Database;
7
8 /**
9  * Create a block and test saving it.
10  *
11  * @group block_content
12  */
13 class BlockContentCreationTest extends BlockContentTestBase {
14
15   /**
16    * Modules to enable.
17    *
18    * Enable dummy module that implements hook_block_insert() for exceptions and
19    * field_ui to edit display settings.
20    *
21    * @var array
22    */
23   public static $modules = ['block_content_test', 'dblog', 'field_ui'];
24
25   /**
26    * Permissions to grant admin user.
27    *
28    * @var array
29    */
30   protected $permissions = [
31     'administer blocks',
32     'administer block_content display',
33   ];
34
35   /**
36    * Sets the test up.
37    */
38   protected function setUp() {
39     parent::setUp();
40     $this->drupalLogin($this->adminUser);
41   }
42
43   /**
44    * Creates a "Basic page" block and verifies its consistency in the database.
45    */
46   public function testBlockContentCreation() {
47     $this->drupalLogin($this->adminUser);
48
49     // Create a block.
50     $edit = [];
51     $edit['info[0][value]'] = 'Test Block';
52     $edit['body[0][value]'] = $this->randomMachineName(16);
53     $this->drupalPostForm('block/add/basic', $edit, t('Save'));
54
55     // Check that the Basic block has been created.
56     $this->assertRaw(format_string('@block %name has been created.', [
57       '@block' => 'basic',
58       '%name' => $edit['info[0][value]'],
59     ]), 'Basic block created.');
60
61     // Check that the view mode setting is hidden because only one exists.
62     $this->assertNoFieldByXPath('//select[@name="settings[view_mode]"]', NULL, 'View mode setting hidden because only one exists');
63
64     // Check that the block exists in the database.
65     $blocks = \Drupal::entityTypeManager()
66       ->getStorage('block_content')
67       ->loadByProperties(['info' => $edit['info[0][value]']]);
68     $block = reset($blocks);
69     $this->assertTrue($block, 'Custom Block found in database.');
70
71     // Check that attempting to create another block with the same value for
72     // 'info' returns an error.
73     $this->drupalPostForm('block/add/basic', $edit, t('Save'));
74
75     // Check that the Basic block has been created.
76     $this->assertRaw(format_string('A custom block with block description %value already exists.', [
77       '%value' => $edit['info[0][value]'],
78     ]));
79     $this->assertResponse(200);
80   }
81
82   /**
83    * Creates a "Basic page" block with multiple view modes.
84    */
85   public function testBlockContentCreationMultipleViewModes() {
86     // Add a new view mode and verify if it is selected as expected.
87     $this->drupalLogin($this->drupalCreateUser(['administer display modes']));
88     $this->drupalGet('admin/structure/display-modes/view/add/block_content');
89     $edit = [
90       'id' => 'test_view_mode',
91       'label' => 'Test View Mode',
92     ];
93     $this->drupalPostForm(NULL, $edit, t('Save'));
94     $this->assertRaw(t('Saved the %label view mode.', ['%label' => $edit['label']]));
95
96     $this->drupalLogin($this->adminUser);
97
98     // Create a block.
99     $edit = [];
100     $edit['info[0][value]'] = 'Test Block';
101     $edit['body[0][value]'] = $this->randomMachineName(16);
102     $this->drupalPostForm('block/add/basic', $edit, t('Save'));
103
104     // Check that the Basic block has been created.
105     $this->assertRaw(format_string('@block %name has been created.', [
106       '@block' => 'basic',
107       '%name' => $edit['info[0][value]'],
108     ]), 'Basic block created.');
109
110     // Save our block permanently
111     $this->drupalPostForm(NULL, ['region' => 'content'], t('Save block'));
112
113     // Set test_view_mode as a custom display to be available on the list.
114     $this->drupalGet('admin/structure/block/block-content');
115     $this->drupalGet('admin/structure/block/block-content/types');
116     $this->clickLink(t('Manage display'));
117     $this->drupalGet('admin/structure/block/block-content/manage/basic/display');
118     $custom_view_mode = [
119       'display_modes_custom[test_view_mode]' => 1,
120     ];
121     $this->drupalPostForm(NULL, $custom_view_mode, t('Save'));
122
123     // Go to the configure page and change the view mode.
124     $this->drupalGet('admin/structure/block/manage/testblock');
125
126     // Test the available view mode options.
127     $this->assertOption('edit-settings-view-mode', 'default', 'The default view mode is available.');
128     $this->assertOption('edit-settings-view-mode', 'test_view_mode', 'The test view mode is available.');
129
130     $view_mode['settings[view_mode]'] = 'test_view_mode';
131     $this->drupalPostForm(NULL, $view_mode, t('Save block'));
132
133     // Check that the view mode setting is shown because more than one exists.
134     $this->drupalGet('admin/structure/block/manage/testblock');
135     $this->assertFieldByXPath('//select[@name="settings[view_mode]"]', NULL, 'View mode setting shown because multiple exist');
136
137     // Change the view mode.
138     $view_mode['region'] = 'content';
139     $view_mode['settings[view_mode]'] = 'test_view_mode';
140     $this->drupalPostForm(NULL, $view_mode, t('Save block'));
141
142     // Go to the configure page and verify the view mode has changed.
143     $this->drupalGet('admin/structure/block/manage/testblock');
144     $this->assertFieldByXPath('//select[@name="settings[view_mode]"]/option[@selected="selected"]', 'test_view_mode', 'View mode changed to Test View Mode');
145
146     // Check that the block exists in the database.
147     $blocks = \Drupal::entityTypeManager()
148       ->getStorage('block_content')
149       ->loadByProperties(['info' => $edit['info[0][value]']]);
150     $block = reset($blocks);
151     $this->assertTrue($block, 'Custom Block found in database.');
152
153     // Check that attempting to create another block with the same value for
154     // 'info' returns an error.
155     $this->drupalPostForm('block/add/basic', $edit, t('Save'));
156
157     // Check that the Basic block has been created.
158     $this->assertRaw(format_string('A custom block with block description %value already exists.', [
159       '%value' => $edit['info[0][value]'],
160     ]));
161     $this->assertResponse(200);
162   }
163
164   /**
165    * Create a default custom block.
166    *
167    * Creates a custom block from defaults and ensures that the 'basic block'
168    * type is being used.
169    */
170   public function testDefaultBlockContentCreation() {
171     $edit = [];
172     $edit['info[0][value]'] = $this->randomMachineName(8);
173     $edit['body[0][value]'] = $this->randomMachineName(16);
174     // Don't pass the custom block type in the url so the default is forced.
175     $this->drupalPostForm('block/add', $edit, t('Save'));
176
177     // Check that the block has been created and that it is a basic block.
178     $this->assertRaw(format_string('@block %name has been created.', [
179       '@block' => 'basic',
180       '%name' => $edit['info[0][value]'],
181     ]), 'Basic block created.');
182
183     // Check that the block exists in the database.
184     $blocks = \Drupal::entityTypeManager()
185       ->getStorage('block_content')
186       ->loadByProperties(['info' => $edit['info[0][value]']]);
187     $block = reset($blocks);
188     $this->assertTrue($block, 'Default Custom Block found in database.');
189   }
190
191   /**
192    * Verifies that a transaction rolls back the failed creation.
193    */
194   public function testFailedBlockCreation() {
195     // Create a block.
196     try {
197       $this->createBlockContent('fail_creation');
198       $this->fail('Expected exception has not been thrown.');
199     }
200     catch (\Exception $e) {
201       $this->pass('Expected exception has been thrown.');
202     }
203
204     if (Database::getConnection()->supportsTransactions()) {
205       // Check that the block does not exist in the database.
206       $id = db_select('block_content_field_data', 'b')
207         ->fields('b', ['id'])
208         ->condition('info', 'fail_creation')
209         ->execute()
210         ->fetchField();
211       $this->assertFalse($id, 'Transactions supported, and block not found in database.');
212     }
213     else {
214       // Check that the block exists in the database.
215       $id = db_select('block_content_field_data', 'b')
216         ->fields('b', ['id'])
217         ->condition('info', 'fail_creation')
218         ->execute()
219         ->fetchField();
220       $this->assertTrue($id, 'Transactions not supported, and block found in database.');
221
222       // Check that the failed rollback was logged.
223       $records = db_query("SELECT wid FROM {watchdog} WHERE message LIKE 'Explicit rollback failed%'")->fetchAll();
224       $this->assertTrue(count($records) > 0, 'Transactions not supported, and rollback error logged to watchdog.');
225     }
226   }
227
228   /**
229    * Test deleting a block.
230    */
231   public function testBlockDelete() {
232     // Create a block.
233     $edit = [];
234     $edit['info[0][value]'] = $this->randomMachineName(8);
235     $body = $this->randomMachineName(16);
236     $edit['body[0][value]'] = $body;
237     $this->drupalPostForm('block/add/basic', $edit, t('Save'));
238
239     // Place the block.
240     $instance = [
241       'id' => mb_strtolower($edit['info[0][value]']),
242       'settings[label]' => $edit['info[0][value]'],
243       'region' => 'sidebar_first',
244     ];
245     $block = BlockContent::load(1);
246     $url = 'admin/structure/block/add/block_content:' . $block->uuid() . '/' . $this->config('system.theme')->get('default');
247     $this->drupalPostForm($url, $instance, t('Save block'));
248
249     $block = BlockContent::load(1);
250
251     // Test getInstances method.
252     $this->assertEqual(1, count($block->getInstances()));
253
254     // Navigate to home page.
255     $this->drupalGet('');
256     $this->assertText($body);
257
258     // Delete the block.
259     $this->drupalGet('block/1/delete');
260     $this->assertText(\Drupal::translation()->formatPlural(1, 'This will also remove 1 placed block instance.', 'This will also remove @count placed block instance.'));
261
262     $this->drupalPostForm(NULL, [], 'Delete');
263     $this->assertRaw(t('The custom block %name has been deleted.', ['%name' => $edit['info[0][value]']]));
264
265     // Create another block and force the plugin cache to flush.
266     $edit2 = [];
267     $edit2['info[0][value]'] = $this->randomMachineName(8);
268     $body2 = $this->randomMachineName(16);
269     $edit2['body[0][value]'] = $body2;
270     $this->drupalPostForm('block/add/basic', $edit2, t('Save'));
271
272     $this->assertNoRaw('Error message');
273
274     // Create another block with no instances, and test we don't get a
275     // confirmation message about deleting instances.
276     $edit3 = [];
277     $edit3['info[0][value]'] = $this->randomMachineName(8);
278     $body = $this->randomMachineName(16);
279     $edit3['body[0][value]'] = $body;
280     $this->drupalPostForm('block/add/basic', $edit3, t('Save'));
281
282     // Show the delete confirm form.
283     $this->drupalGet('block/3/delete');
284     $this->assertNoText('This will also remove');
285   }
286
287   /**
288    * Test that placed content blocks create a dependency in the block placement.
289    */
290   public function testConfigDependencies() {
291     $block = $this->createBlockContent();
292     // Place the block.
293     $block_placement_id = mb_strtolower($block->label());
294     $instance = [
295       'id' => $block_placement_id,
296       'settings[label]' => $block->label(),
297       'region' => 'sidebar_first',
298     ];
299     $block = BlockContent::load(1);
300     $url = 'admin/structure/block/add/block_content:' . $block->uuid() . '/' . $this->config('system.theme')->get('default');
301     $this->drupalPostForm($url, $instance, t('Save block'));
302
303     $dependencies = \Drupal::service('config.manager')->findConfigEntityDependentsAsEntities('content', [$block->getConfigDependencyName()]);
304     $block_placement = reset($dependencies);
305     $this->assertEqual($block_placement_id, $block_placement->id(), "The block placement config entity has a dependency on the block content entity.");
306   }
307
308 }