7cf953af740b0682b5349f5fc82e6e9a40db0fd5
[yaffs-website] / web / core / modules / views / tests / src / Kernel / ViewStorageTest.php
1 <?php
2
3 namespace Drupal\Tests\views\Kernel;
4
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;
9
10 /**
11  * Tests the CRUD functionality for a view.
12  *
13  * @group views
14  * @see \Drupal\views\Entity\View
15  * @see \Drupal\Core\Config\Entity\ConfigEntityStorage
16  */
17 class ViewStorageTest extends ViewsKernelTestBase {
18
19   /**
20    * Properties that should be stored in the configuration.
21    *
22    * @var array
23    */
24   protected $configProperties = [
25     'status',
26     'module',
27     'id',
28     'description',
29     'tag',
30     'base_table',
31     'label',
32     'core',
33     'display',
34   ];
35
36   /**
37    * The entity type definition.
38    *
39    * @var \Drupal\Core\Entity\EntityTypeInterface
40    */
41   protected $entityType;
42
43   /**
44    * The configuration entity storage.
45    *
46    * @var \Drupal\Core\Config\Entity\ConfigEntityStorage
47    */
48   protected $controller;
49
50   /**
51    * Views used by this test.
52    *
53    * @var array
54    */
55   public static $testViews = ['test_view_storage'];
56
57   /**
58    * Tests CRUD operations.
59    */
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');
64
65     // Confirm that an info array has been returned.
66     $this->assertTrue($this->entityType instanceof EntityTypeInterface, 'The View info array is loaded.');
67
68     // CRUD tests.
69     $this->loadTests();
70     $this->createTests();
71     $this->displayTests();
72
73     // Helper method tests
74     $this->displayMethodTests();
75   }
76
77   /**
78    * Tests loading configuration entities.
79    */
80   protected function loadTests() {
81     $view = View::load('test_view_storage');
82     $data = $this->config('views.view.test_view_storage')->get();
83
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]));
89     }
90
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.');
94
95     // Check each ViewDisplay object and confirm that it has the correct key and
96     // property values.
97     foreach ($view->get('display') as $key => $display) {
98       $this->assertEqual($key, $display['id'], 'The display has the correct ID assigned.');
99
100       // Get original display data and confirm that the display options array
101       // exists.
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]));
105       }
106     }
107
108     // Make sure that loaded default views get a UUID.
109     $view = Views::getView('test_view_storage');
110     $this->assertTrue($view->storage->uuid());
111   }
112
113   /**
114    * Tests creating configuration entities.
115    */
116   protected function createTests() {
117     // Create a new View instance with empty values.
118     $created = $this->controller->create([]);
119
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]));
124     }
125
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);
131
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);
137
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]));
142     }
143
144     // Check the UUID of the loaded View.
145     $created->save();
146     $created_loaded = View::load('test_view_storage_new');
147     $this->assertIdentical($created->uuid(), $created_loaded->uuid(), 'The created UUID has been saved correctly.');
148   }
149
150   /**
151    * Tests adding, saving, and loading displays on configuration entities.
152    */
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');
156
157     $new_id = $view->addDisplay('page', 'Test', 'test');
158     $display = $view->get('display');
159
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.');
162
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.');
166
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');
170     $view->save();
171     $values = $this->config('views.view.test_view_storage_new_new2')->get();
172
173     $this->assertTrue(isset($values['display']['test']) && is_array($values['display']['test']), 'New display was saved.');
174   }
175
176   /**
177    * Tests the display related functions like getDisplaysList().
178    */
179   protected function displayMethodTests() {
180     $config['display'] = [
181       'page_1' => [
182         'display_options' => ['path' => 'test'],
183         'display_plugin' => 'page',
184         'id' => 'page_2',
185         'display_title' => 'Page 1',
186         'position' => 1
187       ],
188       'feed_1' => [
189         'display_options' => ['path' => 'test.xml'],
190         'display_plugin' => 'feed',
191         'id' => 'feed',
192         'display_title' => 'Feed',
193         'position' => 2
194       ],
195       'page_2' => [
196         'display_options' => ['path' => 'test/%/extra'],
197         'display_plugin' => 'page',
198         'id' => 'page_2',
199         'display_title' => 'Page 2',
200         'position' => 3
201       ]
202     ];
203     $view = $this->controller->create($config);
204
205     // Tests Drupal\views\Entity\View::addDisplay()
206     $view = $this->controller->create([]);
207     $random_title = $this->randomMachineName();
208
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);
213
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);
219
220     $id = $view->addDisplay('page');
221     $display = $view->get('display');
222     $this->assertEqual($display[$id]['display_title'], 'Page 3');
223
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
227     // title.
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');
232
233     // Tests Drupal\views\Entity\View::generateDisplayId(). Since
234     // generateDisplayId() is protected, we have to use reflection to unit-test
235     // it.
236     $view = $this->controller->create([]);
237     $ref_generate_display_id = new \ReflectionMethod($view, 'generateDisplayId');
238     $ref_generate_display_id->setAccessible(TRUE);
239     $this->assertEqual(
240       $ref_generate_display_id->invoke($view, 'default'),
241       'default',
242       'The plugin ID for default is always default.'
243     );
244     $this->assertEqual(
245       $ref_generate_display_id->invoke($view, 'feed'),
246       'feed_1',
247       'The generated ID for the first instance of a plugin type should have an suffix of _1.'
248     );
249     $view->addDisplay('feed', 'feed title');
250     $this->assertEqual(
251       $ref_generate_display_id->invoke($view, 'feed'),
252       'feed_2',
253       'The generated ID for the first instance of a plugin type should have an suffix of _2.'
254     );
255
256     // Tests item related methods().
257     $view = $this->controller->create(['base_table' => 'views_test_data']);
258     $view->addDisplay('default');
259     $view = $view->getExecutable();
260
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
265     // options.
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 = [
269       'id' => 'id',
270       'table' => 'views_test_data',
271       'field' => 'id',
272       'plugin_id' => 'numeric',
273     ];
274     $this->assertEqual($item1, $expected_item);
275
276     $options = [
277       'alter' => [
278         'text' => $this->randomMachineName()
279       ]
280     ];
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 = [
284       'id' => 'name',
285       'table' => 'views_test_data',
286       'field' => 'name',
287       'plugin_id' => 'standard',
288     ] + $options;
289     $this->assertEqual($item2, $expected_item);
290
291     // Tests the expected fields from the previous additions.
292     $this->assertEqual($view->getHandlers('field', $display_id), $expected_items);
293
294     // Alter an existing item via setItem and check the result via getItem
295     // and getItems.
296     $item = [
297       'alter' => [
298         'text' => $this->randomMachineName(),
299       ]
300     ] + $item1;
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);
305
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);
310   }
311
312   /**
313    * Tests the createDuplicate() View method.
314    */
315   public function testCreateDuplicate() {
316     $view = Views::getView('test_view_storage');
317     $copy = $view->storage->createDuplicate();
318
319     $this->assertTrue($copy instanceof View, 'The copied object is a View.');
320
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.');
323
324     // Check the 'name' (ID) is using the View objects default value (NULL) as it
325     // gets unset.
326     $this->assertIdentical($copy->id(), NULL, 'The ID has been reset.');
327
328     // Check the other properties.
329     // @todo Create a reusable property on the base test class for these?
330     $config_properties = [
331       'disabled',
332       'description',
333       'tag',
334       'base_table',
335       'label',
336       'core',
337     ];
338
339     foreach ($config_properties as $property) {
340       $this->assertIdentical($view->storage->get($property), $copy->get($property), format_string('@property property is identical.', ['@property' => $property]));
341     }
342
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]));
348     }
349   }
350
351 }