77
88namespace SprykerTest \Client \Testify \Helper ;
99
10- use Codeception \Configuration ;
1110use Codeception \Module ;
1211use Codeception \Stub ;
1312use Codeception \TestInterface ;
1413use Exception ;
14+ use Spryker \Client \Kernel \AbstractBundleConfig ;
15+ use Spryker \Client \Kernel \AbstractClient ;
16+ use Spryker \Client \Kernel \AbstractFactory ;
17+ use Spryker \Client \Kernel \Container ;
1518use SprykerTest \Shared \Testify \Helper \ClassResolverTrait ;
19+ use SprykerTest \Shared \Testify \Helper \ModuleNameTrait ;
20+ use Throwable ;
1621
1722class ClientHelper extends Module
1823{
1924 use ClassResolverTrait;
25+ use ModuleNameTrait;
26+ use ConfigHelperTrait;
27+ use DependencyProviderHelperTrait;
2028
2129 protected const CLIENT_CLASS_NAME_PATTERN = '\%1$s\Client\%3$s\%3$sClient ' ;
22- protected const MODULE_NAME_POSITION = 2 ;
30+ protected const CLIENT_FACTORY_CLASS_NAME_PATTERN = ' \%1$s\Client\%3$s\%3$sFactory ' ;
2331
2432 /**
2533 * @var \Spryker\Client\Kernel\AbstractClient[]
@@ -31,6 +39,16 @@ class ClientHelper extends Module
3139 */
3240 protected $ mockedClientMethods = [];
3341
42+ /**
43+ * @var \Spryker\Client\Kernel\AbstractFactory[]
44+ */
45+ protected $ factoryStubs = [];
46+
47+ /**
48+ * @var array
49+ */
50+ protected $ mockedFactoryMethods = [];
51+
3452 /**
3553 * @param string $methodName
3654 * @param mixed $return
@@ -70,43 +88,168 @@ public function getClient(?string $moduleName = null)
7088 {
7189 $ moduleName = $ this ->getModuleName ($ moduleName );
7290
73- if (isset ($ this ->clientStubs [$ moduleName ])) {
74- return $ this ->clientStubs [$ moduleName ];
91+ if (! isset ($ this ->clientStubs [$ moduleName ])) {
92+ $ this ->clientStubs [$ moduleName ] = $ this -> createClient ( $ moduleName ) ;
7593 }
7694
77- $ client = $ this ->createClient ($ moduleName );
95+ $ this ->clientStubs [$ moduleName ] = $ this ->injectFactory ($ this ->clientStubs [$ moduleName ], $ moduleName );
96+
97+ return $ this ->clientStubs [$ moduleName ];
98+ }
99+
100+ /**
101+ * @param string|null $moduleName
102+ *
103+ * @return \Spryker\Client\Kernel\AbstractClient
104+ */
105+ protected function createClient (?string $ moduleName = null )
106+ {
107+ $ moduleName = $ this ->getModuleName ($ moduleName );
108+ $ moduleClientClassName = $ this ->resolveClassName (static ::CLIENT_CLASS_NAME_PATTERN , $ moduleName );
109+
110+ return new $ moduleClientClassName ();
111+ }
112+
113+ /**
114+ * @param \Spryker\Client\Kernel\AbstractClient $client
115+ * @param string $moduleName
116+ *
117+ * @return \Spryker\Client\Kernel\AbstractClient
118+ */
119+ protected function injectFactory (AbstractClient $ client , string $ moduleName ): AbstractClient
120+ {
121+ $ client ->setFactory ($ this ->getFactory ($ moduleName ));
78122
79123 return $ client ;
80124 }
81125
82126 /**
127+ * @param string $methodName
128+ * @param mixed $return
83129 * @param string|null $moduleName
84130 *
85- * @return string
131+ * @throws \Exception
132+ *
133+ * @return object|\Spryker\Client\Kernel\AbstractFactory
86134 */
87- protected function getModuleName ( ?string $ moduleName = null ): string
135+ public function mockFactoryMethod ( string $ methodName , $ return , ?string $ moduleName = null )
88136 {
89- if ($ moduleName ) {
90- return $ moduleName ;
137+ $ moduleName = $ this ->getModuleName ($ moduleName );
138+ $ className = $ this ->resolveClassName (static ::CLIENT_FACTORY_CLASS_NAME_PATTERN , $ moduleName );
139+
140+ if (!method_exists ($ className , $ methodName )) {
141+ throw new Exception (sprintf ('You tried to mock a not existing method "%s". Available methods are "%s" ' , $ methodName , implode (', ' , get_class_methods ($ className ))));
142+ }
143+
144+ if (!isset ($ this ->mockedFactoryMethods [$ moduleName ])) {
145+ $ this ->mockedFactoryMethods [$ moduleName ] = [];
91146 }
92147
93- $ config = Configuration::config ();
94- $ namespaceParts = explode ('\\' , $ config ['namespace ' ]);
148+ $ this ->mockedFactoryMethods [$ moduleName ][$ methodName ] = $ return ;
149+ /** @var \Spryker\Client\Kernel\AbstractFactory $factoryStub */
150+ $ factoryStub = Stub::make ($ className , $ this ->mockedFactoryMethods [$ moduleName ]);
151+ $ this ->factoryStubs [$ moduleName ] = $ factoryStub ;
95152
96- return $ namespaceParts [ static :: MODULE_NAME_POSITION ];
153+ return $ this -> factoryStubs [ $ moduleName ];
97154 }
98155
99156 /**
100157 * @param string|null $moduleName
101158 *
102- * @return \Spryker\Client\Kernel\AbstractClient
159+ * @return \Spryker\Client\Kernel\AbstractFactory
103160 */
104- protected function createClient (?string $ moduleName = null )
161+ public function getFactory (?string $ moduleName = null ): AbstractFactory
105162 {
106163 $ moduleName = $ this ->getModuleName ($ moduleName );
107- $ moduleClientClassName = $ this ->resolveClassName (static ::CLIENT_CLASS_NAME_PATTERN , $ moduleName );
108164
109- return new $ moduleClientClassName ();
165+ if (isset ($ this ->factoryStubs [$ moduleName ])) {
166+ $ this ->factoryStubs [$ moduleName ] = $ this ->injectConfig ($ this ->factoryStubs [$ moduleName ], $ moduleName );
167+ $ this ->factoryStubs [$ moduleName ] = $ this ->injectContainer ($ this ->factoryStubs [$ moduleName ], $ moduleName );
168+
169+ return $ this ->factoryStubs [$ moduleName ];
170+ }
171+
172+ $ moduleFactory = $ this ->createFactory ($ moduleName );
173+
174+ $ moduleFactory = $ this ->injectConfig ($ moduleFactory , $ moduleName );
175+ $ moduleFactory = $ this ->injectContainer ($ moduleFactory , $ moduleName );
176+
177+ return $ moduleFactory ;
178+ }
179+
180+ /**
181+ * @param string $moduleName
182+ *
183+ * @return \Spryker\Client\Kernel\AbstractFactory
184+ */
185+ protected function createFactory (string $ moduleName ): AbstractFactory
186+ {
187+ $ moduleFactoryClassName = $ this ->resolveClassName (static ::CLIENT_FACTORY_CLASS_NAME_PATTERN , $ moduleName );
188+
189+ return new $ moduleFactoryClassName ();
190+ }
191+
192+ /**
193+ * @param \Spryker\Client\Kernel\AbstractFactory $clientFactory
194+ * @param string $moduleName
195+ *
196+ * @return \Spryker\Client\Kernel\AbstractFactory
197+ */
198+ protected function injectConfig (AbstractFactory $ clientFactory , string $ moduleName ): AbstractFactory
199+ {
200+ if (!$ this ->hasModule ('\\' . ConfigHelper::class)) {
201+ return $ clientFactory ;
202+ }
203+
204+ $ config = $ this ->getConfig ($ moduleName );
205+
206+ if ($ config !== null ) {
207+ $ clientFactory ->setConfig ($ config );
208+ }
209+
210+ return $ clientFactory ;
211+ }
212+
213+ /**
214+ * @param string $moduleName
215+ *
216+ * @return \Spryker\Client\Kernel\AbstractBundleConfig|null
217+ */
218+ protected function getConfig (string $ moduleName ): ?AbstractBundleConfig
219+ {
220+ try {
221+ /** @var \Spryker\Client\Kernel\AbstractBundleConfig $moduleConfig */
222+ $ moduleConfig = $ this ->getConfigHelper ()->getModuleConfig ($ moduleName );
223+
224+ return $ moduleConfig ;
225+ } catch (Throwable $ throwable ) {
226+ return null ;
227+ }
228+ }
229+
230+ /**
231+ * @param \Spryker\Client\Kernel\AbstractFactory $factory
232+ * @param string $moduleName
233+ *
234+ * @return \Spryker\Client\Kernel\AbstractFactory
235+ */
236+ protected function injectContainer (AbstractFactory $ factory , string $ moduleName ): AbstractFactory
237+ {
238+ if ($ this ->hasModule ('\\' . DependencyProviderHelper::class)) {
239+ $ factory ->setContainer ($ this ->getContainer ($ moduleName ));
240+ }
241+
242+ return $ factory ;
243+ }
244+
245+ /**
246+ * @param string $moduleName
247+ *
248+ * @return \Spryker\Client\Kernel\Container
249+ */
250+ protected function getContainer (string $ moduleName ): Container
251+ {
252+ return $ this ->getDependencyProviderHelper ()->getModuleContainer ($ moduleName );
110253 }
111254
112255 /**
@@ -118,5 +261,7 @@ public function _before(TestInterface $test)
118261 {
119262 $ this ->clientStubs = [];
120263 $ this ->mockedClientMethods = [];
264+ $ this ->factoryStubs = [];
265+ $ this ->mockedFactoryMethods = [];
121266 }
122267}
0 commit comments