Skip to content

Commit 9823457

Browse files
committed
Merge remote-tracking branch 'origin/MAGETWO-72009' into 2.3-develop-pr3
2 parents 88149bf + 2d9f002 commit 9823457

File tree

2 files changed

+177
-81
lines changed

2 files changed

+177
-81
lines changed

app/code/Magento/Deploy/Model/Filesystem.php

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Magento\Framework\App\DeploymentConfig\Writer;
1111
use Magento\Framework\App\Filesystem\DirectoryList;
1212
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\Validator\Locale;
1314
use Magento\User\Model\ResourceModel\User\Collection as UserCollection;
1415

1516
/**
@@ -100,6 +101,11 @@ class Filesystem
100101
*/
101102
private $userCollection;
102103

104+
/**
105+
* @var Locale
106+
*/
107+
private $locale;
108+
103109
/**
104110
* @param \Magento\Framework\App\DeploymentConfig\Writer $writer
105111
* @param \Magento\Framework\App\DeploymentConfig\Reader $reader
@@ -109,6 +115,9 @@ class Filesystem
109115
* @param \Magento\Framework\Filesystem\Driver\File $driverFile
110116
* @param \Magento\Store\Model\Config\StoreView $storeView
111117
* @param \Magento\Framework\ShellInterface $shell
118+
* @param UserCollection|null $userCollection
119+
* @param Locale|null $locale
120+
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
112121
*/
113122
public function __construct(
114123
\Magento\Framework\App\DeploymentConfig\Writer $writer,
@@ -118,7 +127,9 @@ public function __construct(
118127
\Magento\Framework\App\Filesystem\DirectoryList $directoryList,
119128
\Magento\Framework\Filesystem\Driver\File $driverFile,
120129
\Magento\Store\Model\Config\StoreView $storeView,
121-
\Magento\Framework\ShellInterface $shell
130+
\Magento\Framework\ShellInterface $shell,
131+
UserCollection $userCollection = null,
132+
Locale $locale = null
122133
) {
123134
$this->writer = $writer;
124135
$this->reader = $reader;
@@ -128,6 +139,8 @@ public function __construct(
128139
$this->driverFile = $driverFile;
129140
$this->storeView = $storeView;
130141
$this->shell = $shell;
142+
$this->userCollection = $userCollection ?: $this->objectManager->get(UserCollection::class);
143+
$this->locale = $locale ?: $this->objectManager->get(Locale::class);
131144
$this->functionCallPath =
132145
PHP_BINARY . ' -f ' . BP . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'magento ';
133146
}
@@ -193,42 +206,37 @@ protected function deployStaticContent(
193206
private function getAdminUserInterfaceLocales()
194207
{
195208
$locales = [];
196-
foreach ($this->getUserCollection() as $user) {
209+
foreach ($this->userCollection as $user) {
197210
$locales[] = $user->getInterfaceLocale();
198211
}
199212
return $locales;
200213
}
201214

202215
/**
203-
* Get used store and admin user locales
216+
* Get used store and admin user locales.
204217
*
205218
* @return array
219+
* @throws \InvalidArgumentException if unknown locale is provided by the store configuration
206220
*/
207221
private function getUsedLocales()
208222
{
209223
$usedLocales = array_merge(
210224
$this->storeView->retrieveLocales(),
211225
$this->getAdminUserInterfaceLocales()
212226
);
213-
return array_unique($usedLocales);
214-
}
215227

216-
/**
217-
* Get user collection
218-
*
219-
* @return UserCollection
220-
* @deprecated 100.1.0 Added to not break backward compatibility of the constructor signature
221-
* by injecting the new dependency directly.
222-
* The method can be removed in a future major release, when constructor signature can be changed.
223-
*/
224-
private function getUserCollection()
225-
{
226-
if (!($this->userCollection instanceof UserCollection)) {
227-
return \Magento\Framework\App\ObjectManager::getInstance()->get(
228-
UserCollection::class
229-
);
230-
}
231-
return $this->userCollection;
228+
return array_map(
229+
function ($locale) {
230+
if (!$this->locale->isValid($locale)) {
231+
throw new \InvalidArgumentException(
232+
$locale . ' argument has invalid value, run info:language:list for list of available locales'
233+
);
234+
}
235+
236+
return $locale;
237+
},
238+
array_unique($usedLocales)
239+
);
232240
}
233241

234242
/**

app/code/Magento/Deploy/Test/Unit/Model/FilesystemTest.php

Lines changed: 148 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -5,47 +5,64 @@
55
*/
66
namespace Magento\Deploy\Test\Unit\Model;
77

8+
use Magento\Deploy\Model\Filesystem as DeployFilesystem;
9+
use Magento\Framework\Filesystem;
10+
use Magento\Framework\Filesystem\Directory\WriteInterface;
11+
use Magento\Framework\ObjectManagerInterface;
12+
use Magento\Framework\ShellInterface;
13+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
14+
use Magento\Store\Model\Config\StoreView;
15+
use Magento\User\Model\ResourceModel\User\Collection;
16+
use Magento\User\Model\User;
17+
use PHPUnit_Framework_MockObject_MockObject as MockObject;
18+
use Symfony\Component\Console\Output\OutputInterface;
19+
use Magento\Framework\Validator\Locale;
20+
use Magento\Framework\Setup\Lists;
21+
22+
/**
23+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
24+
*/
825
class FilesystemTest extends \PHPUnit\Framework\TestCase
926
{
1027
/**
11-
* @var \Magento\Store\Model\Config\StoreView
28+
* @var StoreView|MockObject
1229
*/
13-
private $storeViewMock;
30+
private $storeView;
1431

1532
/**
16-
* @var \Magento\Framework\ShellInterface
33+
* @var ShellInterface|MockObject
1734
*/
18-
private $shellMock;
35+
private $shell;
1936

2037
/**
21-
* @var \Magento\User\Model\ResourceModel\User\Collection
38+
* @var OutputInterface|MockObject
2239
*/
23-
private $userCollectionMock;
40+
private $output;
2441

2542
/**
26-
* @var \Symfony\Component\Console\Output\OutputInterface
43+
* @var Filesystem|MockObject
2744
*/
28-
private $outputMock;
45+
private $filesystem;
2946

3047
/**
31-
* @var \Magento\Framework\Filesystem
48+
* @var WriteInterface|MockObject
3249
*/
33-
private $filesystemMock;
50+
private $directoryWrite;
3451

3552
/**
36-
* @var \Magento\Framework\Filesystem\Directory\WriteInterface
53+
* @var Collection|MockObject
3754
*/
38-
private $directoryWriteMock;
55+
private $userCollection;
3956

4057
/**
41-
* @var \Magento\Framework\ObjectManagerInterface
58+
* @var ObjectManagerInterface|MockObject
4259
*/
43-
private $objectManagerMock;
60+
private $objectManager;
4461

4562
/**
46-
* @var \Magento\Deploy\Model\Filesystem
63+
* @var DeployFilesystem
4764
*/
48-
private $filesystem;
65+
private $deployFilesystem;
4966

5067
/**
5168
* @var string
@@ -54,75 +71,146 @@ class FilesystemTest extends \PHPUnit\Framework\TestCase
5471

5572
protected function setUp()
5673
{
57-
$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
58-
59-
$this->storeViewMock = $this->createMock(\Magento\Store\Model\Config\StoreView::class);
60-
$this->shellMock = $this->createMock(\Magento\Framework\ShellInterface::class);
61-
$this->userCollectionMock = $this->createMock(\Magento\User\Model\ResourceModel\User\Collection::class);
62-
$this->outputMock = $this->createMock(\Symfony\Component\Console\Output\OutputInterface::class);
63-
$this->objectManagerMock = $this->createMock(\Magento\Framework\ObjectManagerInterface::class);
64-
$this->filesystemMock = $this->createMock(\Magento\Framework\Filesystem::class);
65-
$this->directoryWriteMock = $this->createMock(\Magento\Framework\Filesystem\Directory\WriteInterface::class);
66-
$this->filesystemMock->expects($this->any())
67-
->method('getDirectoryWrite')
68-
->willReturn($this->directoryWriteMock);
69-
$this->filesystem = $objectManager->getObject(
70-
\Magento\Deploy\Model\Filesystem::class,
74+
$objectManager = new ObjectManager($this);
75+
76+
$this->storeView = $this->getMockBuilder(StoreView::class)
77+
->disableOriginalConstructor()
78+
->getMock();
79+
$this->shell = $this->getMockBuilder(ShellInterface::class)
80+
->disableOriginalConstructor()
81+
->getMock();
82+
$this->output = $this->getMockBuilder(OutputInterface::class)
83+
->disableOriginalConstructor()
84+
->getMock();
85+
$this->objectManager = $this->getMockBuilder(ObjectManagerInterface::class)
86+
->disableOriginalConstructor()
87+
->getMock();
88+
$this->filesystem = $this->getMockBuilder(Filesystem::class)
89+
->disableOriginalConstructor()
90+
->getMock();
91+
$this->directoryWrite = $this->getMockBuilder(WriteInterface::class)
92+
->disableOriginalConstructor()
93+
->getMock();
94+
$this->filesystem->method('getDirectoryWrite')
95+
->willReturn($this->directoryWrite);
96+
97+
$this->userCollection = $this->getMockBuilder(Collection::class)
98+
->disableOriginalConstructor()
99+
->getMock();
100+
$lists = $this->getMockBuilder(Lists::class)
101+
->disableOriginalConstructor()
102+
->getMock();
103+
104+
$lists->method('getLocaleList')
105+
->willReturn([
106+
'fr_FR' => 'France',
107+
'de_DE' => 'Germany',
108+
'nl_NL' => 'Netherlands',
109+
'en_US' => 'USA',
110+
]);
111+
$locale = $objectManager->getObject(Locale::class, ['lists' => $lists]);
112+
113+
$this->deployFilesystem = $objectManager->getObject(
114+
DeployFilesystem::class,
71115
[
72-
'storeView' => $this->storeViewMock,
73-
'shell' => $this->shellMock,
74-
'filesystem' => $this->filesystemMock
116+
'storeView' => $this->storeView,
117+
'shell' => $this->shell,
118+
'filesystem' => $this->filesystem,
119+
'userCollection' => $this->userCollection,
120+
'locale' => $locale,
75121
]
76122
);
77123

78-
$userCollection = new \ReflectionProperty(\Magento\Deploy\Model\Filesystem::class, 'userCollection');
79-
$userCollection->setAccessible(true);
80-
$userCollection->setValue($this->filesystem, $this->userCollectionMock);
81-
82124
$this->cmdPrefix = PHP_BINARY . ' -f ' . BP . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'magento ';
83125
}
84126

85127
public function testRegenerateStatic()
86128
{
87129
$storeLocales = ['fr_FR', 'de_DE', 'nl_NL'];
88-
$adminUserInterfaceLocales = ['de_DE', 'en_US'];
89-
$this->storeViewMock->expects($this->once())
90-
->method('retrieveLocales')
130+
$this->storeView->method('retrieveLocales')
91131
->willReturn($storeLocales);
92-
$userMock = $this->createMock(\Magento\User\Model\User::class);
93-
$userMock->expects($this->once())
94-
->method('getInterfaceLocale')
95-
->willReturn('en_US');
96-
$this->userCollectionMock->expects($this->once())
97-
->method('getIterator')
98-
->willReturn(new \ArrayIterator([$userMock]));
99-
100-
$usedLocales = array_unique(
101-
array_merge($storeLocales, $adminUserInterfaceLocales)
102-
);
103-
$staticContentDeployCmd = $this->cmdPrefix . 'setup:static-content:deploy -f '
104-
. implode(' ', $usedLocales);
132+
105133
$setupDiCompileCmd = $this->cmdPrefix . 'setup:di:compile';
106-
$this->shellMock->expects($this->at(0))
134+
$this->shell->expects(self::at(0))
107135
->method('execute')
108136
->with($setupDiCompileCmd);
109-
$this->shellMock->expects($this->at(1))
137+
138+
$this->initAdminLocaleMock('en_US');
139+
140+
$usedLocales = ['fr_FR', 'de_DE', 'nl_NL', 'en_US'];
141+
$staticContentDeployCmd = $this->cmdPrefix . 'setup:static-content:deploy -f '
142+
. implode(' ', $usedLocales);
143+
$this->shell->expects(self::at(1))
110144
->method('execute')
111145
->with($staticContentDeployCmd);
112146

113-
$this->outputMock->expects($this->at(0))
147+
$this->output->expects(self::at(0))
114148
->method('writeln')
115149
->with('Starting compilation');
116-
$this->outputMock->expects($this->at(2))
150+
$this->output->expects(self::at(2))
117151
->method('writeln')
118152
->with('Compilation complete');
119-
$this->outputMock->expects($this->at(3))
153+
$this->output->expects(self::at(3))
120154
->method('writeln')
121155
->with('Starting deployment of static content');
122-
$this->outputMock->expects($this->at(5))
156+
$this->output->expects(self::at(5))
123157
->method('writeln')
124158
->with('Deployment of static content complete');
125159

126-
$this->filesystem->regenerateStatic($this->outputMock);
160+
$this->deployFilesystem->regenerateStatic($this->output);
161+
}
162+
163+
/**
164+
* Checks a case when configuration contains incorrect locale code.
165+
*
166+
* @return void
167+
* @expectedException \InvalidArgumentException
168+
* @expectedExceptionMessage ;echo argument has invalid value, run info:language:list for list of available locales
169+
*/
170+
public function testGenerateStaticForNotAllowedStoreViewLocale()
171+
{
172+
$storeLocales = ['fr_FR', 'de_DE', ';echo'];
173+
$this->storeView->method('retrieveLocales')
174+
->willReturn($storeLocales);
175+
176+
$this->initAdminLocaleMock('en_US');
177+
178+
$this->deployFilesystem->regenerateStatic($this->output);
179+
}
180+
181+
/**
182+
* Checks as case when admin locale is incorrect.
183+
*
184+
* @return void
185+
* @expectedException \InvalidArgumentException
186+
* @expectedExceptionMessage ;echo argument has invalid value, run info:language:list for list of available locales
187+
*/
188+
public function testGenerateStaticForNotAllowedAdminLocale()
189+
{
190+
$storeLocales = ['fr_FR', 'de_DE', 'en_US'];
191+
$this->storeView->method('retrieveLocales')
192+
->willReturn($storeLocales);
193+
194+
$this->initAdminLocaleMock(';echo');
195+
196+
$this->deployFilesystem->regenerateStatic($this->output);
197+
}
198+
199+
/**
200+
* Initializes admin user locale.
201+
*
202+
* @param string $locale
203+
* @return void
204+
*/
205+
private function initAdminLocaleMock($locale)
206+
{
207+
/** @var User|MockObject $user */
208+
$user = $this->getMockBuilder(User::class)
209+
->disableOriginalConstructor()
210+
->getMock();
211+
$user->method('getInterfaceLocale')
212+
->willReturn($locale);
213+
$this->userCollection->method('getIterator')
214+
->willReturn(new \ArrayIterator([$user]));
127215
}
128216
}

0 commit comments

Comments
 (0)