3 namespace Drupal\Tests\views\Kernel;
5 use Drupal\Core\Entity\EntityTypeInterface;
6 use Drupal\views\Entity\View;
7 use Drupal\views\Plugin\views\display\Page;
8 use Drupal\views\Views;
11 * Tests the CRUD functionality for a view.
14 * @see \Drupal\views\Entity\View
15 * @see \Drupal\Core\Config\Entity\ConfigEntityStorage
17 class ViewStorageTest extends ViewsKernelTestBase {
20 * Properties that should be stored in the configuration.
24 protected $configProperties = [
37 * The entity type definition.
39 * @var \Drupal\Core\Entity\EntityTypeInterface
41 protected $entityType;
44 * The configuration entity storage.
46 * @var \Drupal\Core\Config\Entity\ConfigEntityStorage
48 protected $controller;
51 * Views used by this test.
55 public static $testViews = ['test_view_storage'];
58 * Tests CRUD operations.
60 public function testConfigurationEntityCRUD() {
61 // Get the configuration entity type and controller.
62 $this->entityType = \Drupal::entityManager()->getDefinition('view');
63 $this->controller = $this->container->get('entity.manager')->getStorage('view');
65 // Confirm that an info array has been returned.
66 $this->assertTrue($this->entityType instanceof EntityTypeInterface, 'The View info array is loaded.');
71 $this->displayTests();
73 // Helper method tests
74 $this->displayMethodTests();
78 * Tests loading configuration entities.
80 protected function loadTests() {
81 $view = View::load('test_view_storage');
82 $data = $this->config('views.view.test_view_storage')->get();
84 // Confirm that an actual view object is loaded and that it returns all of
85 // expected properties.
86 $this->assertTrue($view instanceof View, 'Single View instance loaded.');
87 foreach ($this->configProperties as $property) {
88 $this->assertTrue($view->get($property) !== NULL, format_string('Property: @property loaded onto View.', ['@property' => $property]));
91 // Check the displays have been loaded correctly from config display data.
92 $expected_displays = ['default', 'block_1', 'page_1'];
93 $this->assertEqual(array_keys($view->get('display')), $expected_displays, 'The correct display names are present.');
95 // Check each ViewDisplay object and confirm that it has the correct key and
97 foreach ($view->get('display') as $key => $display) {
98 $this->assertEqual($key, $display['id'], 'The display has the correct ID assigned.');
100 // Get original display data and confirm that the display options array
102 $original_options = $data['display'][$key];
103 foreach ($original_options as $orig_key => $value) {
104 $this->assertIdentical($display[$orig_key], $value, format_string('@key is identical to saved data', ['@key' => $key]));
108 // Make sure that loaded default views get a UUID.
109 $view = Views::getView('test_view_storage');
110 $this->assertTrue($view->storage->uuid());
114 * Tests creating configuration entities.
116 protected function createTests() {
117 // Create a new View instance with empty values.
118 $created = $this->controller->create([]);
120 $this->assertTrue($created instanceof View, 'Created object is a View.');
121 // Check that the View contains all of the properties.
122 foreach ($this->configProperties as $property) {
123 $this->assertTrue(property_exists($created, $property), format_string('Property: @property created on View.', ['@property' => $property]));
126 // Create a new View instance with config values.
127 $values = $this->config('views.view.test_view_storage')->get();
128 $values['id'] = 'test_view_storage_new';
129 unset($values['uuid']);
130 $created = $this->controller->create($values);
132 $this->assertTrue($created instanceof View, 'Created object is a View.');
133 // Check that the View contains all of the properties.
134 $properties = $this->configProperties;
135 // Remove display from list.
136 array_pop($properties);
138 // Test all properties except displays.
139 foreach ($properties as $property) {
140 $this->assertTrue($created->get($property) !== NULL, format_string('Property: @property created on View.', ['@property' => $property]));
141 $this->assertIdentical($values[$property], $created->get($property), format_string('Property value: @property matches configuration value.', ['@property' => $property]));
144 // Check the UUID of the loaded View.
146 $created_loaded = View::load('test_view_storage_new');
147 $this->assertIdentical($created->uuid(), $created_loaded->uuid(), 'The created UUID has been saved correctly.');
151 * Tests adding, saving, and loading displays on configuration entities.
153 protected function displayTests() {
154 // Check whether a display can be added and saved to a View.
155 $view = View::load('test_view_storage_new');
157 $new_id = $view->addDisplay('page', 'Test', 'test');
158 $display = $view->get('display');
160 // Ensure the right display_plugin is created/instantiated.
161 $this->assertEqual($display[$new_id]['display_plugin'], 'page', 'New page display "test" uses the right display plugin.');
163 $executable = $view->getExecutable();
164 $executable->initDisplay();
165 $this->assertTrue($executable->displayHandlers->get($new_id) instanceof Page, 'New page display "test" uses the right display plugin.');
167 // To save this with a new ID, we should use createDuplicate().
168 $view = $view->createDuplicate();
169 $view->set('id', 'test_view_storage_new_new2');
171 $values = $this->config('views.view.test_view_storage_new_new2')->get();
173 $this->assertTrue(isset($values['display']['test']) && is_array($values['display']['test']), 'New display was saved.');
177 * Tests the display related functions like getDisplaysList().
179 protected function displayMethodTests() {
180 $config['display'] = [
182 'display_options' => ['path' => 'test'],
183 'display_plugin' => 'page',
185 'display_title' => 'Page 1',
189 'display_options' => ['path' => 'test.xml'],
190 'display_plugin' => 'feed',
192 'display_title' => 'Feed',
196 'display_options' => ['path' => 'test/%/extra'],
197 'display_plugin' => 'page',
199 'display_title' => 'Page 2',
203 $view = $this->controller->create($config);
205 // Tests Drupal\views\Entity\View::addDisplay()
206 $view = $this->controller->create([]);
207 $random_title = $this->randomMachineName();
209 $id = $view->addDisplay('page', $random_title);
210 $this->assertEqual($id, 'page_1', format_string('Make sure the first display (%id_new) has the expected ID (%id)', ['%id_new' => $id, '%id' => 'page_1']));
211 $display = $view->get('display');
212 $this->assertEqual($display[$id]['display_title'], $random_title);
214 $random_title = $this->randomMachineName();
215 $id = $view->addDisplay('page', $random_title);
216 $display = $view->get('display');
217 $this->assertEqual($id, 'page_2', format_string('Make sure the second display (%id_new) has the expected ID (%id)', ['%id_new' => $id, '%id' => 'page_2']));
218 $this->assertEqual($display[$id]['display_title'], $random_title);
220 $id = $view->addDisplay('page');
221 $display = $view->get('display');
222 $this->assertEqual($display[$id]['display_title'], 'Page 3');
224 // Ensure the 'default' display always has position zero, regardless of when
225 // it was set relative to other displays. Even if the 'default' display
226 // exists, adding it again will overwrite it, which is asserted with the new
228 $view->addDisplay('default', $random_title);
229 $displays = $view->get('display');
230 $this->assertEqual($displays['default']['display_title'], $random_title, 'Default display is defined with the new title');
231 $this->assertEqual($displays['default']['position'], 0, 'Default displays are always in position zero');
233 // Tests Drupal\views\Entity\View::generateDisplayId(). Since
234 // generateDisplayId() is protected, we have to use reflection to unit-test
236 $view = $this->controller->create([]);
237 $ref_generate_display_id = new \ReflectionMethod($view, 'generateDisplayId');
238 $ref_generate_display_id->setAccessible(TRUE);
240 $ref_generate_display_id->invoke($view, 'default'),
242 'The plugin ID for default is always default.'
245 $ref_generate_display_id->invoke($view, 'feed'),
247 'The generated ID for the first instance of a plugin type should have an suffix of _1.'
249 $view->addDisplay('feed', 'feed title');
251 $ref_generate_display_id->invoke($view, 'feed'),
253 'The generated ID for the first instance of a plugin type should have an suffix of _2.'
256 // Tests item related methods().
257 $view = $this->controller->create(['base_table' => 'views_test_data']);
258 $view->addDisplay('default');
259 $view = $view->getExecutable();
261 $display_id = 'default';
262 $expected_items = [];
263 // Tests addHandler with getItem.
264 // Therefore add one item without any options and one item with some
266 $id1 = $view->addHandler($display_id, 'field', 'views_test_data', 'id');
267 $item1 = $view->getHandler($display_id, 'field', 'id');
268 $expected_items[$id1] = $expected_item = [
270 'table' => 'views_test_data',
272 'plugin_id' => 'numeric',
274 $this->assertEqual($item1, $expected_item);
278 'text' => $this->randomMachineName()
281 $id2 = $view->addHandler($display_id, 'field', 'views_test_data', 'name', $options);
282 $item2 = $view->getHandler($display_id, 'field', 'name');
283 $expected_items[$id2] = $expected_item = [
285 'table' => 'views_test_data',
287 'plugin_id' => 'standard',
289 $this->assertEqual($item2, $expected_item);
291 // Tests the expected fields from the previous additions.
292 $this->assertEqual($view->getHandlers('field', $display_id), $expected_items);
294 // Alter an existing item via setItem and check the result via getItem
298 'text' => $this->randomMachineName(),
301 $expected_items[$id1] = $item;
302 $view->setHandler($display_id, 'field', $id1, $item);
303 $this->assertEqual($view->getHandler($display_id, 'field', 'id'), $item);
304 $this->assertEqual($view->getHandlers('field', $display_id), $expected_items);
306 // Test removeItem method.
307 unset($expected_items[$id2]);
308 $view->removeHandler($display_id, 'field', $id2);
309 $this->assertEqual($view->getHandlers('field', $display_id), $expected_items);
313 * Tests the createDuplicate() View method.
315 public function testCreateDuplicate() {
316 $view = Views::getView('test_view_storage');
317 $copy = $view->storage->createDuplicate();
319 $this->assertTrue($copy instanceof View, 'The copied object is a View.');
321 // Check that the original view and the copy have different UUIDs.
322 $this->assertNotIdentical($view->storage->uuid(), $copy->uuid(), 'The copied view has a new UUID.');
324 // Check the 'name' (ID) is using the View objects default value (NULL) as it
326 $this->assertIdentical($copy->id(), NULL, 'The ID has been reset.');
328 // Check the other properties.
329 // @todo Create a reusable property on the base test class for these?
330 $config_properties = [
339 foreach ($config_properties as $property) {
340 $this->assertIdentical($view->storage->get($property), $copy->get($property), format_string('@property property is identical.', ['@property' => $property]));
343 // Check the displays are the same.
344 $copy_display = $copy->get('display');
345 foreach ($view->storage->get('display') as $id => $display) {
346 // assertIdentical will not work here.
347 $this->assertEqual($display, $copy_display[$id], format_string('The @display display has been copied correctly.', ['@display' => $id]));