| 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 |