diff --git a/app/code/Magento/Csp/Model/Collector/CspWhitelistXml/FileResolver.php b/app/code/Magento/Csp/Model/Collector/CspWhitelistXml/FileResolver.php index acc0dd1600db..58a7f2e58f12 100644 --- a/app/code/Magento/Csp/Model/Collector/CspWhitelistXml/FileResolver.php +++ b/app/code/Magento/Csp/Model/Collector/CspWhitelistXml/FileResolver.php @@ -1,22 +1,22 @@ moduleFileResolver->get($filename, $scope); - if ($scope === 'global') { - $files = []; - $theme = $this->theme; - while ($theme) { - /** @var CustomizationInterface $info */ - $info = $this->themeInfoFactory->create(['theme' => $theme]); - $file = $info->getThemeFilesPath() .'/etc/' .$filename; - if ($this->rootDir->isExist($file)) { - $files[] = $file; + $configs = $this->moduleFileResolver->get($filename, $scope); + + switch ($scope) { + case 'frontend': + case 'adminhtml': + $files = []; + $theme = $this->theme; + while ($theme) { + /** @var CustomizationInterface $info */ + $info = $this->themeInfoFactory->create(['theme' => $theme]); + $file = $info->getThemeFilesPath() . '/etc/' . $filename; + if ($this->rootDir->isExist($file)) { + $files[] = $file; + } + $theme = $theme->getParentTheme(); } - $theme = $theme->getParentTheme(); - } - $configs = $this->iteratorFactory->create( - ['paths' => array_reverse($files), 'existingIterator' => $configs] - ); + $configs = $this->iteratorFactory->create( + ['paths' => array_reverse($files), 'existingIterator' => $configs] + ); + break; + case 'global': + default: + break; } return $configs; diff --git a/app/code/Magento/Csp/Test/Unit/Model/Collector/CspWhitelistXml/FileResolverTest.php b/app/code/Magento/Csp/Test/Unit/Model/Collector/CspWhitelistXml/FileResolverTest.php new file mode 100644 index 000000000000..cb691d69d10d --- /dev/null +++ b/app/code/Magento/Csp/Test/Unit/Model/Collector/CspWhitelistXml/FileResolverTest.php @@ -0,0 +1,223 @@ +moduleFileResolverMock = $this->getMockBuilder(FileResolverInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->designMock = $this->getMockBuilder(DesignInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->themeInterFaceMock = $this->getMockBuilder(ThemeInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->designMock->expects($this->once()) + ->method('getDesignTheme') + ->willReturn($this->themeInterFaceMock); + + $this->customizationFactoryMock = $this->getMockBuilder(CustomizationInterfaceFactory::class) + ->disableOriginalConstructor() + ->onlyMethods(['create']) + ->getMock(); + + $this->customizationInterfaceMock = $this->getMockBuilder(CustomizationInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->filesystemMock = $this->createPartialMock(Filesystem::class, ['getDirectoryRead']); + + $this->readInterfaceMock = $this->getMockBuilder(ReadInterface::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->filesystemMock->expects($this->once()) + ->method('getDirectoryRead') + ->with(DirectoryList::ROOT) + ->willReturn($this->readInterfaceMock); + + $this->iteratorFactoryMock = $this->getMockBuilder(CompositeFileIteratorFactory::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->model = new FileResolver( + $this->moduleFileResolverMock, + $this->designMock, + $this->customizationFactoryMock, + $this->filesystemMock, + $this->iteratorFactoryMock + ); + } + + /** + * Test for get method with frontend scope. + * + * @param string $scope + * @param string $fileName + * @param array $fileList + * @param string $themeFilesPath + * + * @return void + * @dataProvider providerGetFrontend + */ + public function testGetFrontend(string $scope, string $fileName, array $fileList, string $themeFilesPath): void + { + $this->moduleFileResolverMock->expects($this->once()) + ->method('get') + ->with($fileName, $scope) + ->willReturn($fileList); + + $this->customizationFactoryMock->expects($this->any()) + ->method('create') + ->with(['theme' => $this->themeInterFaceMock]) + ->willReturn($this->customizationInterfaceMock); + + $this->customizationInterfaceMock->expects($this->once()) + ->method('getThemeFilesPath') + ->willReturn($themeFilesPath); + + $this->readInterfaceMock->expects($this->once()) + ->method('isExist') + ->with($themeFilesPath.'/etc/'.$fileName) + ->willReturn(true); + + $this->iteratorFactoryMock->expects($this->once()) + ->method('create') + ->with( + [ + 'paths' => array_reverse([$themeFilesPath.'/etc/'.$fileName]), + 'existingIterator' => $fileList + ] + ) + ->willReturn($fileList); + + $this->assertEquals($fileList, $this->model->get($fileName, $scope)); + } + + /** + * Test for get method with global scope. + * + * @param string $scope + * @param string $fileName + * @param array $fileList + * + * @return void + * @dataProvider providerGetGlobal + */ + public function testGetGlobal(string $scope, string $fileName, array $fileList): void + { + $this->moduleFileResolverMock->expects($this->once()) + ->method('get') + ->with($fileName, $scope) + ->willReturn($fileList); + $this->assertEquals($fileList, $this->model->get($fileName, $scope)); + } + + /** + * Data provider for get global scope tests. + * + * @return array + */ + public static function providerGetGlobal(): array + { + return [ + [ + 'global', + 'csp_whitelist.xml', + ['anyvendor/anymodule/etc/csp_whitelist.xml'] + ] + ]; + } + + /** + * Data provider for get frontend & adminhtml scope tests. + * + * @return array + */ + public static function providerGetFrontend(): array + { + return [ + [ + 'frontend', + 'csp_whitelist.xml', + ['themevendor/theme/etc/csp_whitelist.xml'], + 'themevendor/theme' + ], + [ + 'adminhtml', + 'csp_whitelist.xml', + ['adminthemevendor/admintheme/etc/csp_whitelist.xml'], + 'adminthemevendor/admintheme' + ] + ]; + } +}