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