846ce0a59f2f1305f4fe21808fc2952c2d3988be
[yaffs-website] / web / core / tests / Drupal / Tests / Core / Entity / KeyValueStore / KeyValueEntityStorageTest.php
1 <?php
2
3 namespace Drupal\Tests\Core\Entity\KeyValueStore;
4
5 use Drupal\Core\Config\Entity\ConfigEntityInterface;
6 use Drupal\Core\DependencyInjection\ContainerBuilder;
7 use Drupal\Core\Entity\EntityFieldManagerInterface;
8 use Drupal\Core\Entity\EntityInterface;
9 use Drupal\Core\Entity\EntityMalformedException;
10 use Drupal\Core\Entity\EntityManager;
11 use Drupal\Core\Entity\EntityStorageException;
12 use Drupal\Core\Entity\EntityTypeManagerInterface;
13 use Drupal\Core\Language\Language;
14 use Drupal\Tests\UnitTestCase;
15 use Drupal\Core\Entity\KeyValueStore\KeyValueEntityStorage;
16
17 /**
18  * @coversDefaultClass \Drupal\Core\Entity\KeyValueStore\KeyValueEntityStorage
19  * @group Entity
20  */
21 class KeyValueEntityStorageTest extends UnitTestCase {
22
23   /**
24    * The entity type.
25    *
26    * @var \Drupal\Core\Entity\EntityTypeInterface|\PHPUnit_Framework_MockObject_MockObject
27    */
28   protected $entityType;
29
30   /**
31    * The key value store.
32    *
33    * @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface|\PHPUnit_Framework_MockObject_MockObject
34    */
35   protected $keyValueStore;
36
37   /**
38    * The module handler.
39    *
40    * @var \Drupal\Core\Extension\ModuleHandlerInterface|\PHPUnit_Framework_MockObject_MockObject
41    */
42   protected $moduleHandler;
43
44   /**
45    * The UUID service.
46    *
47    * @var \Drupal\Component\Uuid\UuidInterface|\PHPUnit_Framework_MockObject_MockObject
48    */
49   protected $uuidService;
50
51   /**
52    * The language manager.
53    *
54    * @var \Drupal\Core\Language\LanguageManagerInterface|\PHPUnit_Framework_MockObject_MockObject
55    */
56   protected $languageManager;
57
58   /**
59    * @var \Drupal\Core\Entity\KeyValueStore\KeyValueEntityStorage
60    */
61   protected $entityStorage;
62
63   /**
64    * The entity manager.
65    *
66    * @var \Drupal\Core\Entity\EntityManagerInterface|\PHPUnit_Framework_MockObject_MockObject
67    */
68   protected $entityManager;
69
70   /**
71    * The mocked entity type manager.
72    *
73    * @var \Drupal\Core\Entity\EntityTypeManagerInterface|\PHPUnit_Framework_MockObject_MockObject
74    */
75   protected $entityTypeManager;
76
77   /**
78    * The mocked entity field manager.
79    *
80    * @var \Drupal\Core\Entity\EntityFieldManagerInterface|\PHPUnit_Framework_MockObject_MockObject
81    */
82   protected $entityFieldManager;
83
84   /**
85    * The mocked cache tags invalidator.
86    *
87    * @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface|\PHPUnit_Framework_MockObject_MockObject
88    */
89   protected $cacheTagsInvalidator;
90
91   /**
92    * {@inheritdoc}
93    */
94   protected function setUp() {
95     parent::setUp();
96     $this->entityType = $this->getMock('Drupal\Core\Entity\EntityTypeInterface');
97   }
98
99   /**
100    * Prepares the key value entity storage.
101    *
102    * @covers ::__construct
103    *
104    * @param string $uuid_key
105    *   (optional) The entity key used for the UUID. Defaults to 'uuid'.
106    */
107   protected function setUpKeyValueEntityStorage($uuid_key = 'uuid') {
108     $this->entityType->expects($this->atLeastOnce())
109       ->method('getKey')
110       ->will($this->returnValueMap([
111         ['id', 'id'],
112         ['uuid', $uuid_key],
113         ['langcode', 'langcode'],
114       ]));
115     $this->entityType->expects($this->atLeastOnce())
116       ->method('id')
117       ->will($this->returnValue('test_entity_type'));
118     $this->entityType->expects($this->any())
119       ->method('getListCacheTags')
120       ->willReturn(['test_entity_type_list']);
121
122     $this->entityManager = new EntityManager();
123
124     $this->entityTypeManager = $this->getMock(EntityTypeManagerInterface::class);
125     $this->entityTypeManager->expects($this->any())
126       ->method('getDefinition')
127       ->with('test_entity_type')
128       ->will($this->returnValue($this->entityType));
129
130     $this->entityFieldManager = $this->getMock(EntityFieldManagerInterface::class);
131
132     $this->cacheTagsInvalidator = $this->getMock('Drupal\Core\Cache\CacheTagsInvalidatorInterface');
133
134     $this->keyValueStore = $this->getMock('Drupal\Core\KeyValueStore\KeyValueStoreInterface');
135     $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
136     $this->uuidService = $this->getMock('Drupal\Component\Uuid\UuidInterface');
137     $this->languageManager = $this->getMock('Drupal\Core\Language\LanguageManagerInterface');
138     $language = new Language(['langcode' => 'en']);
139     $this->languageManager->expects($this->any())
140       ->method('getDefaultLanguage')
141       ->will($this->returnValue($language));
142     $this->languageManager->expects($this->any())
143       ->method('getCurrentLanguage')
144       ->will($this->returnValue($language));
145
146     $this->entityStorage = new KeyValueEntityStorage($this->entityType, $this->keyValueStore, $this->uuidService, $this->languageManager);
147     $this->entityStorage->setModuleHandler($this->moduleHandler);
148
149     $container = new ContainerBuilder();
150     $container->set('entity.manager', $this->entityManager);
151     $container->set('entity_field.manager', $this->entityFieldManager);
152     $container->set('entity_type.manager', $this->entityTypeManager);
153     $container->set('language_manager', $this->languageManager);
154     $container->set('cache_tags.invalidator', $this->cacheTagsInvalidator);
155     // Inject the container into entity.manager so it can defer to
156     // entity_type.manager and other services.
157     $this->entityManager->setContainer($container);
158     \Drupal::setContainer($container);
159   }
160
161   /**
162    * @covers ::create
163    * @covers ::doCreate
164    */
165   public function testCreateWithPredefinedUuid() {
166     $this->entityType->expects($this->once())
167       ->method('getClass')
168       ->will($this->returnValue(get_class($this->getMockEntity())));
169     $this->setUpKeyValueEntityStorage();
170
171     $this->moduleHandler->expects($this->at(0))
172       ->method('invokeAll')
173       ->with('test_entity_type_create');
174     $this->moduleHandler->expects($this->at(1))
175       ->method('invokeAll')
176       ->with('entity_create');
177     $this->uuidService->expects($this->never())
178       ->method('generate');
179
180     $entity = $this->entityStorage->create(['id' => 'foo', 'uuid' => 'baz']);
181     $this->assertInstanceOf('Drupal\Core\Entity\EntityInterface', $entity);
182     $this->assertSame('foo', $entity->id());
183     $this->assertSame('baz', $entity->uuid());
184   }
185
186   /**
187    * @covers ::create
188    * @covers ::doCreate
189    */
190   public function testCreateWithoutUuidKey() {
191     // Set up the entity storage to expect no UUID key.
192     $this->entityType->expects($this->once())
193       ->method('getClass')
194       ->will($this->returnValue(get_class($this->getMockEntity())));
195     $this->setUpKeyValueEntityStorage(NULL);
196
197     $this->moduleHandler->expects($this->at(0))
198       ->method('invokeAll')
199       ->with('test_entity_type_create');
200     $this->moduleHandler->expects($this->at(1))
201       ->method('invokeAll')
202       ->with('entity_create');
203     $this->uuidService->expects($this->never())
204       ->method('generate');
205
206     $entity = $this->entityStorage->create(['id' => 'foo', 'uuid' => 'baz']);
207     $this->assertInstanceOf('Drupal\Core\Entity\EntityInterface', $entity);
208     $this->assertSame('foo', $entity->id());
209     $this->assertSame('baz', $entity->uuid());
210   }
211
212   /**
213    * @covers ::create
214    * @covers ::doCreate
215    *
216    * @return \Drupal\Core\Entity\EntityInterface
217    */
218   public function testCreate() {
219     $entity = $this->getMockEntity('Drupal\Core\Entity\Entity', [], ['toArray']);
220     $this->entityType->expects($this->once())
221       ->method('getClass')
222       ->will($this->returnValue(get_class($entity)));
223     $this->setUpKeyValueEntityStorage();
224
225     $this->moduleHandler->expects($this->at(0))
226       ->method('invokeAll')
227       ->with('test_entity_type_create');
228     $this->moduleHandler->expects($this->at(1))
229       ->method('invokeAll')
230       ->with('entity_create');
231     $this->uuidService->expects($this->once())
232       ->method('generate')
233       ->will($this->returnValue('bar'));
234
235     $entity = $this->entityStorage->create(['id' => 'foo']);
236     $this->assertInstanceOf('Drupal\Core\Entity\EntityInterface', $entity);
237     $this->assertSame('foo', $entity->id());
238     $this->assertSame('bar', $entity->uuid());
239     return $entity;
240   }
241
242   /**
243    * @covers ::save
244    * @covers ::doSave
245    *
246    * @param \Drupal\Core\Entity\EntityInterface $entity
247    *
248    * @return \Drupal\Core\Entity\EntityInterface
249    *
250    * @depends testCreate
251    */
252   public function testSaveInsert(EntityInterface $entity) {
253     $this->entityType->expects($this->once())
254       ->method('getClass')
255       ->will($this->returnValue(get_class($entity)));
256     $this->setUpKeyValueEntityStorage();
257
258     $expected = ['id' => 'foo'];
259     $this->keyValueStore->expects($this->exactly(2))
260       ->method('has')
261       ->with('foo')
262       ->will($this->returnValue(FALSE));
263     $this->keyValueStore->expects($this->never())
264       ->method('getMultiple');
265     $this->keyValueStore->expects($this->never())
266       ->method('delete');
267
268     $entity->expects($this->atLeastOnce())
269       ->method('toArray')
270       ->will($this->returnValue($expected));
271
272     $this->moduleHandler->expects($this->at(0))
273       ->method('invokeAll')
274       ->with('test_entity_type_presave');
275     $this->moduleHandler->expects($this->at(1))
276       ->method('invokeAll')
277       ->with('entity_presave');
278     $this->moduleHandler->expects($this->at(2))
279       ->method('invokeAll')
280       ->with('test_entity_type_insert');
281     $this->moduleHandler->expects($this->at(3))
282       ->method('invokeAll')
283       ->with('entity_insert');
284     $this->keyValueStore->expects($this->once())
285       ->method('set')
286       ->with('foo', $expected);
287     $return = $this->entityStorage->save($entity);
288     $this->assertSame(SAVED_NEW, $return);
289     return $entity;
290   }
291
292   /**
293    * @covers ::save
294    * @covers ::doSave
295    *
296    * @param \Drupal\Core\Entity\EntityInterface $entity
297    *
298    * @return \Drupal\Core\Entity\EntityInterface
299    *
300    * @depends testSaveInsert
301    */
302   public function testSaveUpdate(EntityInterface $entity) {
303     $this->entityType->expects($this->once())
304       ->method('getClass')
305       ->will($this->returnValue(get_class($entity)));
306     $this->setUpKeyValueEntityStorage();
307
308     $expected = ['id' => 'foo'];
309     $this->keyValueStore->expects($this->exactly(2))
310       ->method('has')
311       ->with('foo')
312       ->will($this->returnValue(TRUE));
313     $this->keyValueStore->expects($this->once())
314       ->method('getMultiple')
315       ->with(['foo'])
316       ->will($this->returnValue([['id' => 'foo']]));
317     $this->keyValueStore->expects($this->never())
318       ->method('delete');
319
320     $this->moduleHandler->expects($this->at(0))
321       ->method('getImplementations')
322       ->with('entity_load')
323       ->will($this->returnValue([]));
324     $this->moduleHandler->expects($this->at(1))
325       ->method('getImplementations')
326       ->with('test_entity_type_load')
327       ->will($this->returnValue([]));
328     $this->moduleHandler->expects($this->at(2))
329       ->method('invokeAll')
330       ->with('test_entity_type_presave');
331     $this->moduleHandler->expects($this->at(3))
332       ->method('invokeAll')
333       ->with('entity_presave');
334     $this->moduleHandler->expects($this->at(4))
335       ->method('invokeAll')
336       ->with('test_entity_type_update');
337     $this->moduleHandler->expects($this->at(5))
338       ->method('invokeAll')
339       ->with('entity_update');
340     $this->keyValueStore->expects($this->once())
341       ->method('set')
342       ->with('foo', $expected);
343     $return = $this->entityStorage->save($entity);
344     $this->assertSame(SAVED_UPDATED, $return);
345     return $entity;
346   }
347
348   /**
349    * @covers ::save
350    * @covers ::doSave
351    */
352   public function testSaveConfigEntity() {
353     $this->setUpKeyValueEntityStorage();
354
355     $entity = $this->getMockEntity('Drupal\Core\Config\Entity\ConfigEntityBase', [['id' => 'foo']], [
356       'toArray',
357       'preSave',
358     ]);
359     $entity->enforceIsNew();
360     // When creating a new entity, the ID is tracked as the original ID.
361     $this->assertSame('foo', $entity->getOriginalId());
362
363     $expected = ['id' => 'foo'];
364     $entity->expects($this->atLeastOnce())
365       ->method('toArray')
366       ->will($this->returnValue($expected));
367
368     $this->keyValueStore->expects($this->exactly(2))
369       ->method('has')
370       ->with('foo')
371       ->will($this->returnValue(FALSE));
372     $this->keyValueStore->expects($this->once())
373       ->method('set')
374       ->with('foo', $expected);
375     $this->keyValueStore->expects($this->never())
376       ->method('delete');
377
378     $return = $this->entityStorage->save($entity);
379     $this->assertSame(SAVED_NEW, $return);
380     return $entity;
381   }
382
383   /**
384    * @covers ::save
385    * @covers ::doSave
386    *
387    * @depends testSaveConfigEntity
388    */
389   public function testSaveRenameConfigEntity(ConfigEntityInterface $entity) {
390     $this->entityType->expects($this->once())
391       ->method('getClass')
392       ->will($this->returnValue(get_class($entity)));
393     $this->setUpKeyValueEntityStorage();
394
395     $this->moduleHandler->expects($this->at(0))
396       ->method('getImplementations')
397       ->with('entity_load')
398       ->will($this->returnValue([]));
399     $this->moduleHandler->expects($this->at(1))
400       ->method('getImplementations')
401       ->with('test_entity_type_load')
402       ->will($this->returnValue([]));
403     $expected = ['id' => 'foo'];
404     $entity->expects($this->once())
405       ->method('toArray')
406       ->will($this->returnValue($expected));
407     $this->keyValueStore->expects($this->exactly(2))
408       ->method('has')
409       ->with('foo')
410       ->will($this->returnValue(TRUE));
411     $this->keyValueStore->expects($this->once())
412       ->method('getMultiple')
413       ->with(['foo'])
414       ->will($this->returnValue([['id' => 'foo']]));
415     $this->keyValueStore->expects($this->once())
416       ->method('delete')
417       ->with('foo');
418     $this->keyValueStore->expects($this->once())
419       ->method('set')
420       ->with('bar', $expected);
421
422     // Performing a rename does not change the original ID until saving.
423     $this->assertSame('foo', $entity->getOriginalId());
424     $entity->set('id', 'bar');
425     $this->assertSame('foo', $entity->getOriginalId());
426
427     $return = $this->entityStorage->save($entity);
428     $this->assertSame(SAVED_UPDATED, $return);
429     $this->assertSame('bar', $entity->getOriginalId());
430   }
431
432   /**
433    * @covers ::save
434    * @covers ::doSave
435    */
436   public function testSaveContentEntity() {
437     $this->entityType->expects($this->any())
438       ->method('getKeys')
439       ->will($this->returnValue([
440         'id' => 'id',
441       ]));
442     $this->setUpKeyValueEntityStorage();
443
444     $expected = ['id' => 'foo'];
445     $this->keyValueStore->expects($this->exactly(2))
446       ->method('has')
447       ->with('foo')
448       ->will($this->returnValue(FALSE));
449     $this->keyValueStore->expects($this->once())
450       ->method('set')
451       ->with('foo', $expected);
452     $this->keyValueStore->expects($this->never())
453       ->method('delete');
454     $entity = $this->getMockEntity('Drupal\Core\Entity\ContentEntityBase', [], [
455       'toArray',
456       'id',
457     ]);
458     $entity->expects($this->atLeastOnce())
459       ->method('id')
460       ->will($this->returnValue('foo'));
461     $entity->expects($this->once())
462       ->method('toArray')
463       ->will($this->returnValue($expected));
464     $this->entityStorage->save($entity);
465   }
466
467   /**
468    * @covers ::save
469    * @covers ::doSave
470    */
471   public function testSaveInvalid() {
472     $this->setUpKeyValueEntityStorage();
473
474     $entity = $this->getMockEntity('Drupal\Core\Config\Entity\ConfigEntityBase');
475     $this->keyValueStore->expects($this->never())
476       ->method('has');
477     $this->keyValueStore->expects($this->never())
478       ->method('set');
479     $this->keyValueStore->expects($this->never())
480       ->method('delete');
481     $this->setExpectedException(EntityMalformedException::class, 'The entity does not have an ID.');
482     $this->entityStorage->save($entity);
483   }
484
485   /**
486    * @covers ::save
487    * @covers ::doSave
488    */
489   public function testSaveDuplicate() {
490     $this->setUpKeyValueEntityStorage();
491
492     $entity = $this->getMockEntity('Drupal\Core\Entity\Entity', [['id' => 'foo']]);
493     $entity->enforceIsNew();
494     $this->keyValueStore->expects($this->once())
495       ->method('has')
496       ->will($this->returnValue(TRUE));
497     $this->keyValueStore->expects($this->never())
498       ->method('set');
499     $this->keyValueStore->expects($this->never())
500       ->method('delete');
501     $this->setExpectedException(EntityStorageException::class, "'test_entity_type' entity with ID 'foo' already exists");
502     $this->entityStorage->save($entity);
503   }
504
505   /**
506    * @covers ::load
507    * @covers ::postLoad
508    */
509   public function testLoad() {
510     $entity = $this->getMockEntity();
511     $this->entityType->expects($this->once())
512       ->method('getClass')
513       ->will($this->returnValue(get_class($entity)));
514     $this->setUpKeyValueEntityStorage();
515
516     $this->keyValueStore->expects($this->once())
517       ->method('getMultiple')
518       ->with(['foo'])
519       ->will($this->returnValue([['id' => 'foo']]));
520     $this->moduleHandler->expects($this->at(0))
521       ->method('getImplementations')
522       ->with('entity_load')
523       ->will($this->returnValue([]));
524     $this->moduleHandler->expects($this->at(1))
525       ->method('getImplementations')
526       ->with('test_entity_type_load')
527       ->will($this->returnValue([]));
528     $entity = $this->entityStorage->load('foo');
529     $this->assertInstanceOf('Drupal\Core\Entity\EntityInterface', $entity);
530     $this->assertSame('foo', $entity->id());
531   }
532
533   /**
534    * @covers ::load
535    */
536   public function testLoadMissingEntity() {
537     $this->entityType->expects($this->once())
538       ->method('getClass');
539     $this->setUpKeyValueEntityStorage();
540
541     $this->keyValueStore->expects($this->once())
542       ->method('getMultiple')
543       ->with(['foo'])
544       ->will($this->returnValue([]));
545     $this->moduleHandler->expects($this->never())
546       ->method('getImplementations');
547     $entity = $this->entityStorage->load('foo');
548     $this->assertNull($entity);
549   }
550
551   /**
552    * @covers ::loadMultiple
553    * @covers ::postLoad
554    * @covers ::mapFromStorageRecords
555    * @covers ::doLoadMultiple
556    */
557   public function testLoadMultipleAll() {
558     $expected['foo'] = $this->getMockEntity('Drupal\Core\Entity\Entity', [['id' => 'foo']]);
559     $expected['bar'] = $this->getMockEntity('Drupal\Core\Entity\Entity', [['id' => 'bar']]);
560     $this->entityType->expects($this->once())
561       ->method('getClass')
562       ->will($this->returnValue(get_class(reset($expected))));
563     $this->setUpKeyValueEntityStorage();
564
565     $this->keyValueStore->expects($this->once())
566       ->method('getAll')
567       ->will($this->returnValue([['id' => 'foo'], ['id' => 'bar']]));
568     $this->moduleHandler->expects($this->at(0))
569       ->method('getImplementations')
570       ->with('entity_load')
571       ->will($this->returnValue([]));
572     $this->moduleHandler->expects($this->at(1))
573       ->method('getImplementations')
574       ->with('test_entity_type_load')
575       ->will($this->returnValue([]));
576     $entities = $this->entityStorage->loadMultiple();
577     foreach ($entities as $id => $entity) {
578       $this->assertInstanceOf('Drupal\Core\Entity\EntityInterface', $entity);
579       $this->assertSame($id, $entity->id());
580       $this->assertSame($id, $expected[$id]->id());
581     }
582   }
583
584   /**
585    * @covers ::loadMultiple
586    * @covers ::postLoad
587    * @covers ::mapFromStorageRecords
588    * @covers ::doLoadMultiple
589    */
590   public function testLoadMultipleIds() {
591     $entity = $this->getMockEntity('Drupal\Core\Entity\Entity', [['id' => 'foo']]);
592     $this->entityType->expects($this->once())
593       ->method('getClass')
594       ->will($this->returnValue(get_class($entity)));
595     $this->setUpKeyValueEntityStorage();
596
597     $expected[] = $entity;
598     $this->keyValueStore->expects($this->once())
599       ->method('getMultiple')
600       ->with(['foo'])
601       ->will($this->returnValue([['id' => 'foo']]));
602     $this->moduleHandler->expects($this->at(0))
603       ->method('getImplementations')
604       ->with('entity_load')
605       ->will($this->returnValue([]));
606     $this->moduleHandler->expects($this->at(1))
607       ->method('getImplementations')
608       ->with('test_entity_type_load')
609       ->will($this->returnValue([]));
610     $entities = $this->entityStorage->loadMultiple(['foo']);
611     foreach ($entities as $id => $entity) {
612       $this->assertInstanceOf('Drupal\Core\Entity\EntityInterface', $entity);
613       $this->assertSame($id, $entity->id());
614     }
615   }
616
617   /**
618    * @covers ::loadRevision
619    */
620   public function testLoadRevision() {
621     $this->setUpKeyValueEntityStorage();
622
623     $this->assertSame(NULL, $this->entityStorage->loadRevision(1));
624   }
625
626   /**
627    * @covers ::deleteRevision
628    */
629   public function testDeleteRevision() {
630     $this->setUpKeyValueEntityStorage();
631
632     $this->assertSame(NULL, $this->entityStorage->deleteRevision(1));
633   }
634
635   /**
636    * @covers ::delete
637    * @covers ::doDelete
638    */
639   public function testDelete() {
640     $entities['foo'] = $this->getMockEntity('Drupal\Core\Entity\Entity', [['id' => 'foo']]);
641     $entities['bar'] = $this->getMockEntity('Drupal\Core\Entity\Entity', [['id' => 'bar']]);
642     $this->entityType->expects($this->once())
643       ->method('getClass')
644       ->will($this->returnValue(get_class(reset($entities))));
645     $this->setUpKeyValueEntityStorage();
646
647     $this->moduleHandler->expects($this->at(0))
648       ->method('invokeAll')
649       ->with('test_entity_type_predelete');
650     $this->moduleHandler->expects($this->at(1))
651       ->method('invokeAll')
652       ->with('entity_predelete');
653     $this->moduleHandler->expects($this->at(2))
654       ->method('invokeAll')
655       ->with('test_entity_type_predelete');
656     $this->moduleHandler->expects($this->at(3))
657       ->method('invokeAll')
658       ->with('entity_predelete');
659     $this->moduleHandler->expects($this->at(4))
660       ->method('invokeAll')
661       ->with('test_entity_type_delete');
662     $this->moduleHandler->expects($this->at(5))
663       ->method('invokeAll')
664       ->with('entity_delete');
665     $this->moduleHandler->expects($this->at(6))
666       ->method('invokeAll')
667       ->with('test_entity_type_delete');
668     $this->moduleHandler->expects($this->at(7))
669       ->method('invokeAll')
670       ->with('entity_delete');
671
672     $this->keyValueStore->expects($this->once())
673       ->method('deleteMultiple')
674       ->with(['foo', 'bar']);
675     $this->entityStorage->delete($entities);
676   }
677
678   /**
679    * @covers ::delete
680    * @covers ::doDelete
681    */
682   public function testDeleteNothing() {
683     $this->setUpKeyValueEntityStorage();
684
685     $this->moduleHandler->expects($this->never())
686       ->method($this->anything());
687     $this->keyValueStore->expects($this->never())
688       ->method('delete');
689     $this->keyValueStore->expects($this->never())
690       ->method('deleteMultiple');
691
692     $this->entityStorage->delete([]);
693   }
694
695   /**
696    * Creates an entity with specific methods mocked.
697    *
698    * @param string $class
699    *   (optional) The concrete entity class to mock. Defaults to
700    *   'Drupal\Core\Entity\Entity'.
701    * @param array $arguments
702    *   (optional) Arguments to pass to the constructor. An empty set of values
703    *   and an entity type ID will be provided.
704    * @param array $methods
705    *   (optional) The methods to mock.
706    *
707    * @return \Drupal\Core\Entity\EntityInterface|\PHPUnit_Framework_MockObject_MockObject
708    */
709   public function getMockEntity($class = 'Drupal\Core\Entity\Entity', array $arguments = [], $methods = []) {
710     // Ensure the entity is passed at least an array of values and an entity
711     // type ID
712     if (!isset($arguments[0])) {
713       $arguments[0] = [];
714     }
715     if (!isset($arguments[1])) {
716       $arguments[1] = 'test_entity_type';
717     }
718     return $this->getMockForAbstractClass($class, $arguments, '', TRUE, TRUE, TRUE, $methods);
719   }
720
721 }
722
723 namespace Drupal\Core\Entity\KeyValueStore;
724
725 if (!defined('SAVED_NEW')) {
726   define('SAVED_NEW', 1);
727 }
728 if (!defined('SAVED_UPDATED')) {
729   define('SAVED_UPDATED', 2);
730 }