Total Complexity | 51 |
Total Lines | 537 |
Duplicated Lines | 0 % |
Changes | 0 |
Complex classes like GPlayAppsTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use GPlayAppsTest, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
24 | class GPlayAppsTest extends TestCase |
||
25 | { |
||
26 | /** |
||
27 | * @var GPlayApps |
||
28 | */ |
||
29 | private $gplay; |
||
30 | |||
31 | protected function setUp() |
||
32 | { |
||
33 | $gplay = new GPlayApps(); |
||
34 | $cache = new ArrayCache(); |
||
35 | $gplay->setCache($cache); |
||
36 | $this->gplay = $gplay; |
||
37 | } |
||
38 | |||
39 | /** |
||
40 | * @dataProvider provideConstruct |
||
41 | * @param string|null $defaultLocale |
||
42 | * @param string|null $defaultCountry |
||
43 | * @param string $actualLocale |
||
44 | * @param string $actualCountry |
||
45 | */ |
||
46 | public function testConstruct($defaultLocale, $defaultCountry, $actualLocale, $actualCountry): void |
||
47 | { |
||
48 | $gplay = new GPlayApps($defaultLocale, $defaultCountry); |
||
49 | $this->assertSame($gplay->getDefaultLocale(), $actualLocale); |
||
50 | $this->assertSame($gplay->getDefaultCountry(), $actualCountry); |
||
51 | } |
||
52 | |||
53 | /** |
||
54 | * @return array |
||
55 | */ |
||
56 | public function provideConstruct(): array |
||
57 | { |
||
58 | return [ |
||
59 | [null, null, GPlayApps::DEFAULT_LOCALE, GPlayApps::DEFAULT_COUNTRY], |
||
60 | ['ru', null, 'ru_RU', GPlayApps::DEFAULT_COUNTRY], |
||
61 | ['ru_RU', 'ru', 'ru_RU', 'ru'], |
||
62 | ]; |
||
63 | } |
||
64 | |||
65 | /** |
||
66 | * @throws GooglePlayException |
||
67 | */ |
||
68 | public function testGetApp(): void |
||
69 | { |
||
70 | $appId = 'com.google.android.googlequicksearchbox'; |
||
71 | $locale = 'es'; |
||
72 | $country = 'ca'; |
||
73 | |||
74 | $app = $this->gplay->getApp(new RequestApp( |
||
75 | $appId, |
||
76 | $locale, |
||
77 | $country |
||
78 | )); |
||
79 | |||
80 | $this->assertEquals($app->getId(), $appId); |
||
81 | $this->assertEquals($app->getLocale(), LocaleHelper::getNormalizeLocale($locale)); |
||
82 | |||
83 | $app2 = $this->gplay->getApp($appId); |
||
84 | $this->assertEquals($app2->getId(), $appId); |
||
85 | $this->assertEquals($app2->getLocale(), GPlayApps::DEFAULT_LOCALE); |
||
86 | $this->assertNotEquals($app2, $app); |
||
87 | |||
88 | $this->gplay |
||
89 | ->setDefaultLocale($locale) |
||
90 | ->setDefaultCountry($country); |
||
91 | $app3 = $this->gplay->getApp($appId); |
||
92 | $this->assertEquals($app3->getId(), $appId); |
||
93 | $this->assertEquals($app3->getLocale(), LocaleHelper::getNormalizeLocale($locale)); |
||
94 | $this->assertEquals($app3, $app); |
||
95 | } |
||
96 | |||
97 | /** |
||
98 | * @throws GooglePlayException |
||
99 | */ |
||
100 | public function testNotFoundApp(): void |
||
101 | { |
||
102 | $this->expectException(GooglePlayException::class); |
||
103 | $this->expectExceptionMessage('404 Not Found'); |
||
104 | |||
105 | $this->gplay->getApp(new RequestApp('com.example')); |
||
106 | } |
||
107 | |||
108 | /** |
||
109 | * @throws GooglePlayException |
||
110 | */ |
||
111 | public function testGetAppWithEmptyAppId(): void |
||
112 | { |
||
113 | $this->expectException(\InvalidArgumentException::class); |
||
114 | $this->expectExceptionMessage('$id is empty'); |
||
115 | |||
116 | $this->gplay->getApp(new RequestApp('')); |
||
117 | } |
||
118 | |||
119 | /** |
||
120 | * @throws GooglePlayException |
||
121 | */ |
||
122 | public function testGetAppWithNull(): void |
||
123 | { |
||
124 | $this->expectException(\InvalidArgumentException::class); |
||
125 | $this->expectExceptionMessage('$requestApp is null'); |
||
126 | |||
127 | $this->gplay->getApp(null); |
||
128 | } |
||
129 | |||
130 | /** |
||
131 | * @throws GooglePlayException |
||
132 | */ |
||
133 | public function testGetApps(): void |
||
134 | { |
||
135 | /** |
||
136 | * @var RequestApp[] $requests |
||
137 | */ |
||
138 | $requests = [ |
||
139 | 'com.google.android.googlequicksearchbox' => new RequestApp('com.vkontakte.android'), |
||
140 | 'com.android.chrome' => new RequestApp('com.android.chrome'), |
||
141 | ]; |
||
142 | |||
143 | $apps = $this->gplay->getApps($requests); |
||
144 | |||
145 | $this->assertCount(count($requests), $apps); |
||
146 | $this->assertContainsOnlyInstancesOf(AppDetail::class, $apps); |
||
147 | |||
148 | foreach ($requests as $key => $request) { |
||
149 | $this->assertArrayHasKey($key, $apps); |
||
150 | $this->assertEquals($apps[$key]->getId(), $request->getId()); |
||
151 | } |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * @throws GooglePlayException |
||
156 | */ |
||
157 | public function testGetApps2(): void |
||
158 | { |
||
159 | /** |
||
160 | * @var RequestApp[] $requests |
||
161 | */ |
||
162 | $requests = [ |
||
163 | /* 0 => */ |
||
164 | 'com.google.android.googlequicksearchbox', |
||
165 | /* 1 => */ |
||
166 | 'com.android.chrome', |
||
167 | ]; |
||
168 | |||
169 | $apps = $this->gplay->getApps($requests); |
||
170 | |||
171 | $this->assertCount(count($requests), $apps); |
||
172 | $this->assertContainsOnlyInstancesOf(AppDetail::class, $apps); |
||
173 | |||
174 | foreach ($requests as $key => $appId) { |
||
175 | $this->assertIsInt($key); |
||
176 | $this->assertArrayHasKey($key, $apps); |
||
177 | $this->assertEquals($apps[$key]->getId(), $appId); |
||
178 | } |
||
179 | } |
||
180 | |||
181 | |||
182 | /** |
||
183 | * @throws GooglePlayException |
||
184 | */ |
||
185 | public function testGetAppsWithEmptyListIds(): void |
||
186 | { |
||
187 | $appDetails = $this->gplay->getApps([]); |
||
188 | $this->assertIsArray($appDetails); |
||
189 | $this->assertEmpty($appDetails); |
||
190 | } |
||
191 | |||
192 | /** |
||
193 | * @throws GooglePlayException |
||
194 | */ |
||
195 | public function testGetAppsWithAppNotFound(): void |
||
196 | { |
||
197 | $this->expectException(GooglePlayException::class); |
||
198 | $this->expectExceptionMessage('404 Not Found'); |
||
199 | |||
200 | $this->gplay->setConcurrency(1); |
||
201 | $ids = [ |
||
202 | 'com.google.android.webview', |
||
203 | 'com.google.android.apps.authenticator2', |
||
204 | 'com.example', |
||
205 | 'com.android.chrome', |
||
206 | ]; |
||
207 | $this->gplay->getApps($ids); |
||
208 | } |
||
209 | |||
210 | /** |
||
211 | * @throws GooglePlayException |
||
212 | */ |
||
213 | public function testGetAppInAvailableLocales(): void |
||
214 | { |
||
215 | $this->gplay->setConcurrency(10); |
||
216 | |||
217 | $id = 'ru.yandex.metro'; |
||
218 | $apps = $this->gplay->getAppInAvailableLocales($id); |
||
219 | $this->assertContainsOnlyInstancesOf(AppDetail::class, $apps); |
||
220 | |||
221 | $this->assertTrue(count(LocaleHelper::SUPPORTED_LOCALES) > count($apps)); |
||
222 | |||
223 | $this->assertArrayHasKey('ru_RU', $apps); |
||
224 | $this->assertArrayHasKey('uk', $apps); |
||
225 | $this->assertArrayHasKey('tr_TR', $apps); |
||
226 | $this->assertArrayHasKey('en_US', $apps); |
||
227 | |||
228 | $this->assertArrayNotHasKey('th', $apps); |
||
229 | $this->assertArrayNotHasKey('fr_FR', $apps); |
||
230 | $this->assertArrayNotHasKey('fil', $apps); |
||
231 | } |
||
232 | |||
233 | /** |
||
234 | * @throws GooglePlayException |
||
235 | */ |
||
236 | public function testGetAppInAvailableLocalesWithEmptyAppId(): void |
||
237 | { |
||
238 | $this->expectException(\InvalidArgumentException::class); |
||
239 | $this->expectExceptionMessage('$id is empty'); |
||
240 | |||
241 | $this->gplay->getAppInAvailableLocales(''); |
||
242 | } |
||
243 | |||
244 | /** |
||
245 | * @dataProvider providePackageExists |
||
246 | * |
||
247 | * @param string $appId |
||
248 | * @param bool $exists |
||
249 | */ |
||
250 | public function testExistsApp(string $appId, bool $exists): void |
||
251 | { |
||
252 | $this->assertEquals($this->gplay->existsApp($appId), $exists); |
||
253 | } |
||
254 | |||
255 | /** |
||
256 | * @return array |
||
257 | */ |
||
258 | public function providePackageExists(): array |
||
259 | { |
||
260 | return [ |
||
261 | ['com.google.android.gm', true], |
||
262 | ['com.google.android.googlequicksearchbox', true], |
||
263 | ['dc.bloo_free', false], |
||
264 | ['com.test', false], |
||
265 | ['mobi.mgeek.AppToSD', false], |
||
266 | ]; |
||
267 | } |
||
268 | |||
269 | /** |
||
270 | * @throws GooglePlayException |
||
271 | */ |
||
272 | public function testExistsApps(): void |
||
273 | { |
||
274 | $resultsProvider = []; |
||
275 | $requests = []; |
||
276 | foreach ($this->providePackageExists() as $provider) { |
||
277 | [$appId, $actualResult] = $provider; |
||
278 | $resultsProvider[$appId] = $actualResult; |
||
279 | $requests[$appId] = $appId; |
||
280 | } |
||
281 | |||
282 | $existsApps = $this->gplay->existsApps($requests); |
||
283 | foreach ($existsApps as $appId => $result) { |
||
284 | $this->assertEquals($result, $resultsProvider[$appId]); |
||
285 | } |
||
286 | } |
||
287 | |||
288 | /** |
||
289 | * @return array |
||
290 | */ |
||
291 | public function providePackageExistsAsync(): array |
||
292 | { |
||
293 | $data = []; |
||
294 | foreach ($this->providePackageExists() as $provider) { |
||
295 | $data[][$provider[0]] = $provider[1]; |
||
296 | } |
||
297 | return $data; |
||
298 | } |
||
299 | |||
300 | /** |
||
301 | * @throws GooglePlayException |
||
302 | */ |
||
303 | public function testReviews(): void |
||
304 | { |
||
305 | $reviews = $this->gplay->getAppReviews('com.google.android.googlequicksearchbox', 0, SortEnum::NEWEST()); |
||
306 | $reviewsNext = $this->gplay->getAppReviews('com.google.android.googlequicksearchbox', 1, SortEnum::NEWEST()); |
||
307 | |||
308 | $this->assertNotEmpty($reviews); |
||
309 | $this->assertNotEmpty($reviewsNext); |
||
310 | |||
311 | $this->assertContainsOnlyInstancesOf(Review::class, $reviews); |
||
312 | $this->assertContainsOnlyInstancesOf(Review::class, $reviewsNext); |
||
313 | |||
314 | $this->assertNotEquals($reviews, $reviewsNext); |
||
315 | } |
||
316 | |||
317 | public function testAllReviews(): void |
||
318 | { |
||
319 | $allReviews = $this->gplay->getAppAllReviews('com.google.android.googlequicksearchbox', SortEnum::HELPFULNESS(), 300); |
||
320 | $this->assertCount(300, $allReviews); |
||
321 | $this->assertContainsOnlyInstancesOf(Review::class, $allReviews); |
||
322 | } |
||
323 | |||
324 | /** |
||
325 | * @throws GooglePlayException |
||
326 | */ |
||
327 | public function testGetCategories(): void |
||
328 | { |
||
329 | $categories = $this->gplay->getCategories('ru'); |
||
330 | |||
331 | $this->assertNotEmpty($categories); |
||
332 | $this->assertContainsOnlyInstancesOf(Category::class, $categories); |
||
333 | } |
||
334 | |||
335 | /** |
||
336 | * @throws GooglePlayException |
||
337 | */ |
||
338 | public function testGetCategoriesInLocales(): void |
||
339 | { |
||
340 | $categoriesInLocales = $this->gplay->getCategoriesInLocales(['ru', 'en', 'es', 'be', 'fil', 'zh-TW']); |
||
341 | |||
342 | $this->assertNotEmpty($categoriesInLocales); |
||
343 | foreach ($categoriesInLocales as $categories) { |
||
344 | $this->assertContainsOnlyInstancesOf(Category::class, $categories); |
||
345 | } |
||
346 | } |
||
347 | |||
348 | /** |
||
349 | * @throws GooglePlayException |
||
350 | */ |
||
351 | public function testGetCategoriesInAvailableLocales(): void |
||
360 | } |
||
361 | } |
||
362 | |||
363 | /** |
||
364 | * @throws GooglePlayException |
||
365 | */ |
||
366 | public function testDeveloperInfo(): void |
||
367 | { |
||
368 | $devInfo = $this->gplay->getDeveloperInfo(7935948260069539271, 'ru_RU'); |
||
369 | |||
370 | $this->assertNotEmpty($devInfo->getId()); |
||
371 | $this->assertNotEmpty($devInfo->getUrl()); |
||
372 | $this->assertNotEmpty($devInfo->getName()); |
||
373 | $this->assertNotEmpty($devInfo->getDescription()); |
||
374 | $this->assertNotEmpty($devInfo->getWebsite()); |
||
375 | $this->assertNotNull($devInfo->getIcon()); |
||
376 | $this->assertNotNull($devInfo->getHeaderImage()); |
||
377 | $this->assertNull($devInfo->getEmail()); |
||
378 | $this->assertNull($devInfo->getAddress()); |
||
379 | } |
||
380 | |||
381 | /** |
||
382 | * @throws GooglePlayException |
||
383 | */ |
||
384 | public function testDeveloperInfoIncorrectArgument(): void |
||
385 | { |
||
386 | $this->expectException(GooglePlayException::class); |
||
387 | $this->expectExceptionMessage('Developer "Facebook" does not have a personalized page on Google Play.'); |
||
388 | |||
389 | $this->gplay->getDeveloperInfo('Facebook'); |
||
390 | } |
||
391 | |||
392 | /** |
||
393 | * @throws GooglePlayException |
||
394 | */ |
||
395 | public function testDeveloperInfoIncorrectArgument2(): void |
||
396 | { |
||
397 | $this->expectException(GooglePlayException::class); |
||
398 | $this->expectExceptionMessage('Developer "Facebook" does not have a personalized page on Google Play.'); |
||
399 | |||
400 | $app = $this->gplay->getApp(new RequestApp('com.facebook.katana')); |
||
401 | $this->gplay->getDeveloperInfo($app); |
||
402 | } |
||
403 | |||
404 | /** |
||
405 | * @throws GooglePlayException |
||
406 | */ |
||
407 | public function testDeveloperInfoIncorrectArgument3(): void |
||
408 | { |
||
409 | $this->expectException(GooglePlayException::class); |
||
410 | $this->expectExceptionMessage('Developer "Facebook" does not have a personalized page on Google Play.'); |
||
411 | |||
412 | $app = $this->gplay->getApp(new RequestApp('com.facebook.katana')); |
||
413 | $this->gplay->getDeveloperInfo($app->getDeveloper()); |
||
414 | } |
||
415 | |||
416 | /** |
||
417 | * @throws GooglePlayException |
||
418 | */ |
||
419 | public function testDeveloperInfoNotFound(): void |
||
420 | { |
||
421 | $this->expectException(GooglePlayException::class); |
||
422 | $this->expectExceptionMessage('404 Not Found'); |
||
423 | |||
424 | $this->gplay->getDeveloperInfo('353464543535'); |
||
425 | } |
||
426 | |||
427 | /** |
||
428 | * @throws GooglePlayException |
||
429 | */ |
||
430 | public function testDevInfoInLocales(): void |
||
431 | { |
||
432 | $devInfo = $this->gplay->getDeveloperInfoInLocales(5627378377477294831, ['ru_RU', 'uk', 'en', 'fr', 'be']); |
||
433 | |||
434 | $this->assertNotEmpty($devInfo); |
||
435 | $this->assertContainsOnlyInstancesOf(Developer::class, $devInfo); |
||
436 | } |
||
437 | |||
438 | /** |
||
439 | * @throws GooglePlayException |
||
440 | */ |
||
441 | public function testDevInfoInAvailableLocales(): void |
||
442 | { |
||
443 | $developer = $this->gplay->getDeveloperInfoInAvailableLocales(5627378377477294831); |
||
444 | |||
445 | $this->assertNotEmpty($developer); |
||
446 | $this->assertContainsOnlyInstancesOf(Developer::class, $developer); |
||
447 | } |
||
448 | |||
449 | /** |
||
450 | * @throws GooglePlayException |
||
451 | */ |
||
452 | public function testSuggest(): void |
||
456 | } |
||
457 | |||
458 | /** |
||
459 | * @throws GooglePlayException |
||
460 | */ |
||
461 | public function testSearch(): void |
||
462 | { |
||
463 | $results = $this->gplay->search('Mario', 500, PriceEnum::ALL()); |
||
464 | $this->assertNotEmpty($results); |
||
465 | $this->assertCount(GPlayApps::MAX_SEARCH_RESULTS, $results); |
||
466 | |||
467 | $this->assertContainsOnlyInstancesOf(App::class, $results); |
||
468 | } |
||
469 | |||
470 | /** |
||
471 | * @throws GooglePlayException |
||
472 | */ |
||
473 | public function testSimilarApps(): void |
||
474 | { |
||
475 | $count = 70; |
||
476 | $similarApps = $this->gplay->getSimilarApps('com.google.android.apps.docs.editors.docs', $count); |
||
477 | $this->assertNotEmpty($similarApps); |
||
478 | $this->assertCount($count, $similarApps); |
||
479 | $this->assertContainsOnlyInstancesOf(App::class, $similarApps); |
||
480 | } |
||
481 | |||
482 | /** |
||
483 | * @throws GooglePlayException |
||
484 | */ |
||
485 | public function testAppsByCategory(): void |
||
486 | { |
||
487 | $apps = $this->gplay->getAppsByCategory(CategoryEnum::GAME(), CollectionEnum::TOP_FREE(), 140, AgeEnum::FIVE_UNDER(), 'ru', 'ru'); |
||
488 | $this->assertNotEmpty($apps); |
||
489 | $this->assertCount(140, $apps); |
||
490 | $this->assertContainsOnlyInstancesOf(App::class, $apps); |
||
491 | } |
||
492 | |||
493 | /** |
||
494 | * @throws GooglePlayException |
||
495 | */ |
||
496 | public function testPermission(): void |
||
497 | { |
||
498 | $permissions = $this->gplay->getPermissions('com.google.android.apps.docs.editors.docs'); |
||
499 | $this->assertNotEmpty($permissions); |
||
500 | $this->assertContainsOnlyInstancesOf(Permission::class, $permissions); |
||
501 | } |
||
502 | |||
503 | /** |
||
504 | * @throws GooglePlayException |
||
505 | */ |
||
506 | public function testDeveloperApps(): void |
||
507 | { |
||
508 | $developerApps = $this->gplay->getDeveloperApps('5700313618786177705', 'ru_RU', 'by'); |
||
509 | $developerApps2 = $this->gplay->getDeveloperApps('Google LLC', 'ru_RU', 'by'); |
||
510 | |||
511 | $this->assertNotEmpty($developerApps); |
||
512 | $this->assertNotEmpty($developerApps2); |
||
513 | |||
514 | $this->assertContainsOnly(App::class, $developerApps); |
||
515 | $this->assertContainsOnly(App::class, $developerApps2); |
||
516 | } |
||
517 | |||
518 | /** |
||
519 | * @throws GooglePlayException |
||
520 | */ |
||
521 | public function testUseProxy(): void |
||
536 | } |
||
537 | |||
538 | /** |
||
539 | * @param string $proxy |
||
540 | * @return bool |
||
541 | */ |
||
542 | private function isSocks5Proxy(string $proxy): bool |
||
543 | { |
||
544 | $urlComponents = parse_url($proxy); |
||
545 | if ($urlComponents === false || empty($urlComponents['host']) || empty($urlComponents['port'])) { |
||
546 | return false; |
||
547 | } |
||
548 | if ($socket = @fsockopen($urlComponents['host'], $urlComponents['port'])) { |
||
549 | try { |
||
550 | fwrite($socket, pack('C3', 0x05, 0x01, 0x00)); |
||
561 | } |
||
562 | } |
||
563 |