View source
<?php
namespace Drupal\config_filter\Tests;
use Drupal\config_filter\Config\FilteredStorage;
use Drupal\config_filter\Config\FilteredStorageInterface;
use Drupal\config_filter\Config\ReadOnlyStorage;
use Drupal\config_filter\Config\StorageFilterInterface;
use Drupal\config_filter\Exception\InvalidStorageFilterException;
use Drupal\Core\Config\CachedStorage;
use Drupal\Core\Config\StorageInterface;
use Drupal\KernelTests\Core\Config\Storage\CachedStorageTest;
use Prophecy\Argument;
class FilteredStorageTest extends CachedStorageTest {
protected function setUp() : void {
parent::setUp();
$this->storage = new FilteredStorage($this->storage, [
new TransparentFilter(),
]);
}
public function testSettingStorages() {
$filters = static::getProtectedFilters($this->storage);
foreach ($filters as $filter) {
$readonly = $filter
->getPrivateSourceStorage();
$this
->assertInstanceOf(ReadOnlyStorage::class, $readonly);
$readonlyReflection = new \ReflectionClass(ReadOnlyStorage::class);
$storageProperty = $readonlyReflection
->getProperty('storage');
$storageProperty
->setAccessible(TRUE);
$source = $storageProperty
->getValue($readonly);
$this
->assertInstanceOf(CachedStorage::class, $source);
$this
->assertEquals($this->storage, $filter
->getPrivateFilteredStorage());
}
}
public function testCollectionStorages() {
$collection = $this
->randomString();
$this
->assertEquals(StorageInterface::DEFAULT_COLLECTION, $this->storage
->getCollectionName());
$filters = static::getProtectedFilters($this->storage);
foreach ($filters as $filter) {
$this
->assertEquals($this->storage, $filter
->getPrivateFilteredStorage());
$this
->assertEquals(StorageInterface::DEFAULT_COLLECTION, $filter
->getPrivateSourceStorage()
->getCollectionName());
}
$collectionStorage = $this->storage
->createCollection($collection);
$this
->assertInstanceOf(FilteredStorageInterface::class, $collectionStorage);
$collectionFilters = static::getProtectedFilters($collectionStorage);
foreach ($collectionFilters as $filter) {
$this
->assertEquals($collectionStorage, $filter
->getPrivateFilteredStorage());
$this
->assertEquals($collection, $filter
->getPrivateSourceStorage()
->getCollectionName());
}
$filters = static::getProtectedFilters($this->storage);
foreach ($filters as $filter) {
$this
->assertEquals($this->storage, $filter
->getPrivateFilteredStorage());
$this
->assertEquals(StorageInterface::DEFAULT_COLLECTION, $filter
->getPrivateSourceStorage()
->getCollectionName());
}
}
public function testCreateCollectionFilter() {
$collection = $this
->randomString();
$filteredCollection = $this
->randomString();
$filter = $this
->prophesizeFilter();
$filterC = $this
->prophesizeFilter();
$filterC
->filterGetCollectionName($collection)
->willReturn($filteredCollection);
$filter
->filterCreateCollection($collection)
->willReturn($filterC
->reveal());
$source = $this
->prophesize(StorageInterface::class);
$sourceC = $this
->prophesize(StorageInterface::class);
$sourceC
->getCollectionName()
->willReturn($collection);
$source
->createCollection($collection)
->willReturn($sourceC
->reveal());
$storage = new FilteredStorage($source
->reveal(), [
$filter
->reveal(),
]);
$storageC = $storage
->createCollection($collection);
$this
->assertEquals($filteredCollection, $storageC
->getCollectionName());
}
public function testGetAllCollectionNamesFilter() {
$source = $this
->prophesize(StorageInterface::class);
$source
->getAllCollectionNames()
->willReturn([
'a',
'b',
]);
$filter = $this
->prophesizeFilter();
$filter
->filterGetAllCollectionNames([
'a',
'b',
])
->willReturn([
'b',
'b',
'c',
]);
$storage = new FilteredStorage($source
->reveal(), [
$filter
->reveal(),
]);
$this
->assertEquals([
'b',
'c',
], $storage
->getAllCollectionNames());
}
public function testReadFilter($name, $storageMethod, $filterMethod, $data, $expected) {
$source = $this
->prophesize(StorageInterface::class);
$filterA = $this
->prophesizeFilter();
$filterB = $this
->prophesizeFilter();
$source
->{$storageMethod}($name)
->willReturn($data);
$interim = $this
->randomArray();
$filterA
->{$filterMethod}($name, $data)
->willReturn($interim);
$filterB
->{$filterMethod}($name, $interim)
->willReturn($expected);
$storage = new FilteredStorage($source
->reveal(), [
$filterA
->reveal(),
$filterB
->reveal(),
]);
$this
->assertEquals($expected, $storage
->{$storageMethod}($name));
}
public function readFilterProvider() {
return [
[
$this
->randomString(),
'exists',
'filterExists',
TRUE,
TRUE,
],
[
$this
->randomString(),
'exists',
'filterExists',
TRUE,
FALSE,
],
[
$this
->randomString(),
'exists',
'filterExists',
FALSE,
TRUE,
],
[
$this
->randomString(),
'exists',
'filterExists',
FALSE,
FALSE,
],
[
$this
->randomString(),
'read',
'filterRead',
$this
->randomArray(),
$this
->randomArray(),
],
[
$this
->randomString(),
'read',
'filterRead',
NULL,
$this
->randomArray(),
],
[
$this
->randomString(),
'read',
'filterRead',
$this
->randomArray(),
NULL,
],
[
[
$this
->randomString(),
$this
->randomString(),
],
'readMultiple',
'filterReadMultiple',
[
$this
->randomArray(),
$this
->randomArray(),
],
[
$this
->randomArray(),
$this
->randomArray(),
],
],
[
[
$this
->randomString(),
$this
->randomString(),
],
'readMultiple',
'filterReadMultiple',
[
$this
->randomArray(),
FALSE,
],
[
$this
->randomArray(),
$this
->randomArray(),
],
],
];
}
public function testReadMultipleWithEmptyResults() {
$names = [
$this
->randomString(),
$this
->randomString(),
];
$source = $this
->prophesize(StorageInterface::class);
$data = [
$this
->randomArray(),
$this
->randomArray(),
];
$source
->readMultiple($names)
->willReturn($data);
$source = $source
->reveal();
foreach ([
0,
[],
NULL,
] as $none) {
$filtered = $data;
$filtered[1] = $none;
$filter = $this
->prophesizeFilter();
$filter
->filterReadMultiple($names, $data)
->willReturn($filtered);
$storage = new FilteredStorage($source, [
$filter
->reveal(),
]);
$this
->assertEquals([
$data[0],
], $storage
->readMultiple($names));
}
}
public function testWriteFilter($interim, $expected, $exists = TRUE) {
$name = $this
->randomString();
$data = $this
->randomArray();
$source = $this
->prophesize(StorageInterface::class);
$filterA = $this
->prophesizeFilter();
$filterB = $this
->prophesizeFilter();
$filterA
->filterWrite($name, $data)
->willReturn($interim);
$interim = is_array($interim) ? $interim : [];
$filterB
->filterWrite($name, $interim)
->willReturn($expected);
if ($expected) {
$source
->write($name, $expected)
->willReturn(TRUE);
}
else {
$source
->write(Argument::any())
->shouldNotBeCalled();
$source
->exists($name)
->willReturn($exists);
if ($exists) {
$filterA
->filterWriteEmptyIsDelete($name)
->willReturn(TRUE);
$source
->delete($name)
->willReturn(TRUE);
}
}
$storage = new FilteredStorage($source
->reveal(), [
$filterA
->reveal(),
$filterB
->reveal(),
]);
$this
->assertTrue($storage
->write($name, $data));
}
public function writeFilterProvider() {
return [
[
$this
->randomArray(),
$this
->randomArray(),
],
[
NULL,
$this
->randomArray(),
],
[
[],
$this
->randomArray(),
],
[
$this
->randomArray(),
NULL,
FALSE,
],
[
$this
->randomArray(),
[],
FALSE,
],
[
$this
->randomArray(),
NULL,
TRUE,
],
];
}
public function testDeleteFilter($interim, $expected) {
$name = $this
->randomString();
$source = $this
->prophesize(StorageInterface::class);
$filterA = $this
->prophesizeFilter();
$filterB = $this
->prophesizeFilter();
$filterA
->filterDelete($name, TRUE)
->willReturn($interim);
$filterB
->filterDelete($name, $interim)
->willReturn($expected);
if ($expected) {
$source
->delete($name)
->willReturn(TRUE);
}
else {
$source
->delete(Argument::any())
->shouldNotBeCalled();
}
$storage = new FilteredStorage($source
->reveal(), [
$filterA
->reveal(),
$filterB
->reveal(),
]);
$this
->assertEquals($expected, $storage
->delete($name));
}
public function deleteFilterProvider() {
return [
[
TRUE,
TRUE,
],
[
FALSE,
TRUE,
],
[
TRUE,
FALSE,
],
[
FALSE,
FALSE,
],
];
}
public function testRenameFilter($interim, $expected) {
$name = $this
->randomString();
$name2 = $this
->randomString();
$source = $this
->prophesize(StorageInterface::class);
$filterA = $this
->prophesizeFilter();
$filterB = $this
->prophesizeFilter();
$filterA
->filterRename($name, $name2, TRUE)
->willReturn($interim);
$filterB
->filterRename($name, $name2, $interim)
->willReturn($expected);
if ($expected) {
$source
->rename($name, $name2)
->willReturn(TRUE);
}
else {
$source
->rename(Argument::any())
->shouldNotBeCalled();
}
$storage = new FilteredStorage($source
->reveal(), [
$filterA
->reveal(),
$filterB
->reveal(),
]);
$this
->assertEquals($expected, $storage
->rename($name, $name2));
}
public function renameFilterProvider() {
return [
[
TRUE,
TRUE,
],
[
FALSE,
TRUE,
],
[
TRUE,
FALSE,
],
[
FALSE,
FALSE,
],
];
}
public function testDeleteAllFilter($interim, $expected) {
$name = $this
->randomString();
$source = $this
->prophesize(StorageInterface::class);
$filterA = $this
->prophesizeFilter();
$filterB = $this
->prophesizeFilter();
$filterA
->filterDeleteAll($name, TRUE)
->willReturn($interim);
$filterB
->filterDeleteAll($name, $interim)
->willReturn($expected);
if ($expected) {
$source
->deleteAll($name)
->willReturn(TRUE);
}
else {
$source
->deleteAll(Argument::any())
->shouldNotBeCalled();
$all = [
$this
->randomString(),
$this
->randomString(),
];
$source
->listAll($name)
->willReturn($all);
foreach ($all as $item) {
$filterA
->filterDelete($item, TRUE)
->willReturn(TRUE);
$filterB
->filterDelete($item, TRUE)
->willReturn(FALSE);
}
}
$storage = new FilteredStorage($source
->reveal(), [
$filterA
->reveal(),
$filterB
->reveal(),
]);
$this
->assertTrue($storage
->deleteAll($name));
}
public function deleteAllFilterProvider() {
return [
[
TRUE,
TRUE,
],
[
FALSE,
TRUE,
],
[
TRUE,
FALSE,
],
[
FALSE,
FALSE,
],
];
}
public function testInvalidStorageFilterArgument() {
$source = $this
->prophesize(StorageInterface::class);
try {
new FilteredStorage($source
->reveal(), [
new \stdClass(),
]);
$this
->fail('An exception should have been thrown.');
} catch (InvalidStorageFilterException $exception) {
$this
->assertTrue(TRUE);
}
}
protected function prophesizeFilter() {
$filter = $this
->prophesize(StorageFilterInterface::class);
$filter
->setSourceStorage(Argument::type(ReadOnlyStorage::class))
->shouldBeCalledTimes(1);
$filter
->setFilteredStorage(Argument::type(FilteredStorage::class))
->shouldBeCalledTimes(1);
return $filter;
}
protected static function getProtectedFilters(StorageInterface $storage) {
$filterReflection = new \ReflectionClass(FilteredStorage::class);
$filtersProperty = $filterReflection
->getProperty('filters');
$filtersProperty
->setAccessible(TRUE);
return $filtersProperty
->getValue($storage);
}
protected function randomArray($size = 4) {
return (array) $this
->randomObject($size);
}
}