Passed
Push — master ( 80ad96...45165d )
by Alexey
03:00
created

AppBuilderTest::testAppBuilder()   F

Complexity

Conditions 11
Paths > 20000

Size

Total Lines 266
Code Lines 215

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 215
dl 0
loc 266
rs 2.52
c 0
b 0
f 0
cc 11
nc 39366
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
declare(strict_types=1);
3
4
namespace Nelexa\GPlay\Tests\Model\Builder;
5
6
use Nelexa\GPlay\Model\App;
7
use Nelexa\GPlay\Model\AppDetail;
8
use Nelexa\GPlay\Model\Category;
9
use Nelexa\GPlay\Model\Developer;
10
use Nelexa\GPlay\Model\GoogleImage;
11
use Nelexa\GPlay\Model\HistogramRating;
12
use Nelexa\GPlay\Model\ReplyReview;
13
use Nelexa\GPlay\Model\Review;
14
use Nelexa\GPlay\Model\Video;
15
use PHPUnit\Framework\TestCase;
16
17
class AppBuilderTest extends TestCase
18
{
19
    /**
20
     * @dataProvider provideAppBuilderData
21
     * @param array $data
22
     */
23
    public function testAppBuilder(array $data): void
24
    {
25
        $builder = App::newBuilder();
26
27
        try {
28
            new App($builder);
29
            $this->fail('$id is null');
30
        } catch (\InvalidArgumentException $e) {
31
            $this->assertStringContainsString('$id', $e->getMessage());
32
        }
33
34
        $this->assertNull($builder->getUrl());
35
        $builder->setId($data['appId']);
36
        $this->assertSame($builder->getUrl(), $data['appUrl']);
37
38
        $builder->setUrl(null);
39
        try {
40
            new App($builder);
41
            $this->fail('$url is null');
42
        } catch (\InvalidArgumentException $e) {
43
            $this->assertStringContainsString('$url', $e->getMessage());
44
        }
45
46
        $builder->setUrl($data['appUrl']);
47
        try {
48
            new App($builder);
49
            $this->fail('$locale is null');
50
        } catch (\InvalidArgumentException $e) {
51
            $this->assertStringContainsString('$locale', $e->getMessage());
52
        }
53
54
        $builder->setLocale($data['locale']);
55
        try {
56
            new App($builder);
57
            $this->fail('$name is null');
58
        } catch (\InvalidArgumentException $e) {
59
            $this->assertStringContainsString('$name', $e->getMessage());
60
        }
61
62
        $builder->setName($data['appName']);
63
        try {
64
            new App($builder);
65
            $this->fail('$developer is null');
66
        } catch (\InvalidArgumentException $e) {
67
            $this->assertStringContainsString('$developer', $e->getMessage());
68
        }
69
70
        $developer = new Developer(
71
            $devBuilder = Developer::newBuilder()
72
                ->setId($data['developerId'])
73
                ->setUrl($data['developerUrl'])
74
                ->setName($data['developerName'])
75
        );
76
77
        $builder->setDeveloper($developer);
78
        try {
79
            new App($builder);
80
            $this->fail('$icon is null');
81
        } catch (\InvalidArgumentException $e) {
82
            $this->assertStringContainsString('$icon', $e->getMessage());
83
        }
84
85
        $icon = new GoogleImage($data['iconUrl']);
86
        $builder->setIcon($icon);
87
88
        $app = new App($builder);
89
90
        $this->assertInstanceOf(App::class, $app);
91
92
        $this->assertSame($app->getId(), $data['appId']);
93
        $this->assertSame($app->getUrl(), $data['appUrl']);
94
        $this->assertSame($app->getLocale(), $data['locale']);
95
        $this->assertSame($app->getName(), $data['appName']);
96
97
        $this->assertSame($app->getIcon(), $icon);
98
        $this->assertSame($app->getIcon()->getUrl(), $data['iconUrl']);
99
100
        $this->assertSame($app->getDeveloper(), $developer);
101
        $this->assertSame($app->getDeveloper()->getId(), $data['developerId']);
102
        $this->assertSame($app->getDeveloper()->getUrl(), $data['developerUrl']);
103
        $this->assertSame($app->getDeveloper()->getName(), $data['developerName']);
104
105
        $this->assertNull($app->getSummary());
106
        $this->assertSame($app->getScore(), 0.0);
107
        $this->assertNull($app->getPriceText());
108
        $this->assertTrue($app->isFree());
109
110
        $builder
111
            ->setSummary($data['summary'])
112
            ->setScore($data['score'])
113
            ->setPriceText($data['priceText']);
114
115
        $appPaid = new App($builder);
116
        $this->assertNotEquals($app, $appPaid);
117
118
        $this->assertSame($appPaid->getSummary(), $data['summary']);
119
        $this->assertSame($appPaid->getScore(), $data['score']);
120
        $this->assertSame($appPaid->getPriceText(), $data['priceText']);
121
        $this->assertFalse($appPaid->isFree());
122
123
        // AppDetail
124
        try {
125
            new AppDetail($builder);
126
            $this->fail('$description is null or empty');
127
        } catch (\InvalidArgumentException $e) {
128
            $this->assertStringContainsString('$description', $e->getMessage());
129
        }
130
131
        $builder->setDescription($data['description']);
132
        try {
133
            new AppDetail($builder);
134
            $this->fail('$screenshots are empty');
135
        } catch (\InvalidArgumentException $e) {
136
            $this->assertStringContainsString('$screenshots', $e->getMessage());
137
        }
138
139
        foreach ($data['screenshots'] as $screenshot) {
140
            $builder->addScreenshot($screenshot);
141
        }
142
143
        $this->assertSame($builder->getScreenshots(), $data['screenshots']);
144
        $builder->setScreenshots([]);
145
        $this->assertEmpty($builder->getScreenshots());
146
        $builder->setScreenshots($data['screenshots']);
147
        $this->assertSame($builder->getScreenshots(), $data['screenshots']);
148
149
        try {
150
            new AppDetail($builder);
151
            $this->fail('$category is null');
152
        } catch (\InvalidArgumentException $e) {
153
            $this->assertStringContainsString('$category', $e->getMessage());
154
        }
155
156
        $category = new Category($data['categoryId'], $data['categoryName']);
157
        $builder->setCategory($category);
158
159
        $appDetail = new AppDetail($builder);
160
        $this->assertNull($appDetail->getDeveloper()->getDescription());
161
        $this->assertSame($appDetail->getId(), $data['appId']);
162
        $this->assertSame($appDetail->getLocale(), $data['locale']);
163
        $this->assertSame($appDetail->getDescription(), $data['description']);
164
        $this->assertSame($appDetail->getScreenshots(), $data['screenshots']);
165
        $this->assertSame($appDetail->getCategory(), $category);
166
        $this->assertSame($appDetail->getCategory()->getId(), $data['categoryId']);
167
        $this->assertSame($appDetail->getCategory()->getName(), $data['categoryName']);
168
        $this->assertFalse($appDetail->getCategory()->isFamilyCategory());
169
170
        $this->assertNull($appDetail->getTranslatedDescription());
171
        $this->assertNull($appDetail->getTranslatedFromLanguage());
172
        $this->assertNull($appDetail->getHeaderImage());
173
        $this->assertNull($appDetail->getPrivacyPoliceUrl());
174
        $this->assertNull($appDetail->getCategoryFamily());
175
        $this->assertNull($appDetail->getVideo());
176
        $this->assertNull($appDetail->getRecentChanges());
177
        $this->assertFalse($appDetail->isEditorsChoice());
178
        $this->assertSame($appDetail->getInstalls(), 0);
179
        $this->assertSame($appDetail->getNumberVoters(), 0);
180
        $this->assertEquals(
181
            $appDetail->getHistogramRating(),
182
            new HistogramRating(0, 0, 0, 0, 0)
183
        );
184
        $this->assertSame($appDetail->getPrice(), 0.0);
185
        $this->assertSame($appDetail->getCurrency(), 'USD');
186
        $this->assertNull($appDetail->getOffersIAPCost());
187
        $this->assertFalse($appDetail->isOffersIAP());
188
        $this->assertFalse($appDetail->isAdSupported());
189
        $this->assertNull($appDetail->getAppSize());
190
        $this->assertNull($appDetail->getAppVersion());
191
        $this->assertNull($appDetail->getAndroidVersion());
192
        $this->assertNull($appDetail->getMinAndroidVersion());
193
        $this->assertNull($appDetail->getContentRating());
194
        $this->assertNull($appDetail->getReleased());
195
        $this->assertNull($appDetail->getUpdated());
196
        $this->assertSame($appDetail->getReviewsCount(), 0);
197
        $this->assertIsArray($appDetail->getReviews());
198
        $this->assertEmpty($appDetail->getReviews());
199
200
        $categoryFamily = new Category($data['categoryFamilyId'], $data['categoryFamilyName']);
201
        $video = new Video($data['videoThumbUrl'], $data['videoUrl']);
202
203
        $developer = new Developer(
204
            $devBuilder
205
                ->setEmail($data['developerEmail'])
206
                ->setAddress($data['developerAddress'])
207
                ->setWebsite($data['developerSite'])
208
        );
209
210
        $builder
211
            ->setDeveloper($developer)
212
            ->setTranslated($data['translatedDescription'], $data['translatedFromLanguage'])
213
            ->setHeaderImage($data['headerImage'])
214
            ->setPrivacyPoliceUrl($data['privacyPoliceUrl'])
215
            ->setCategoryFamily($categoryFamily)
216
            ->setVideo($video)
217
            ->setRecentChanges($data['recentChanges'])
218
            ->setEditorsChoice($data['editorChoice'])
219
            ->setInstalls($data['installs'])
220
            ->setNumberVoters($data['numberVoters'])
221
            ->setHistogramRating($data['histogramRating'])
222
            ->setPrice($data['price'])
223
            ->setCurrency($data['currency'])
224
            ->setPriceText($data['priceTextEur'])
225
            ->setOffersIAPCost($data['offersIAPCost'])
226
            ->setAdSupported($data['adSupported'])
227
            ->setAppSize($data['appSize'])
228
            ->setAppVersion($data['appVersion'])
229
            ->setAndroidVersion($data['androidVersion'])
230
            ->setMinAndroidVersion($data['minAndroidVersion'])
231
            ->setContentRating($data['contentRating'])
232
            ->setReleased($data['released'])
233
            ->setUpdated($data['updated'])
234
            ->setReviewsCount($data['reviewsCount'])
235
            ->setReviews($data['reviews']);
236
237
        $appDetail = new AppDetail($builder);
238
239
        $this->assertSame($appDetail->getDeveloper(), $developer);
240
        $this->assertSame($appDetail->getDeveloper()->getEmail(), $data['developerEmail']);
241
        $this->assertSame($appDetail->getDeveloper()->getAddress(), $data['developerAddress']);
242
        $this->assertSame($appDetail->getDeveloper()->getWebsite(), $data['developerSite']);
243
        $this->assertNull($appDetail->getDeveloper()->getDescription());
244
        $this->assertNull($appDetail->getDeveloper()->getHeaderImage());
245
        $this->assertNull($appDetail->getDeveloper()->getIcon());
246
247
        $this->assertSame($appDetail->getTranslatedDescription(), $data['translatedDescription']);
248
        $this->assertSame($appDetail->getTranslatedFromLanguage(), $data['translatedFromLanguage']);
249
        $this->assertSame($appDetail->getHeaderImage(), $data['headerImage']);
250
        $this->assertSame($appDetail->getPrivacyPoliceUrl(), $data['privacyPoliceUrl']);
251
        $this->assertSame($appDetail->getCategoryFamily(), $categoryFamily);
252
        $this->assertSame($appDetail->getCategoryFamily()->getId(), $data['categoryFamilyId']);
253
        $this->assertSame($appDetail->getCategoryFamily()->getName(), $data['categoryFamilyName']);
254
        $this->assertTrue($appDetail->getCategoryFamily()->isFamilyCategory());
255
        $this->assertSame($appDetail->getVideo(), $video);
256
        $this->assertSame($appDetail->getVideo()->getThumb(), $data['videoThumbUrl']);
257
        $this->assertSame($appDetail->getVideo()->getUrl(), $data['videoUrl']);
258
        $this->assertSame($appDetail->getVideo()->getYoutubeId(), $data['youtubeId']);
259
        $this->assertSame($appDetail->getRecentChanges(), $data['recentChanges']);
260
        $this->assertSame($appDetail->isEditorsChoice(), $data['editorChoice']);
261
        $this->assertSame($appDetail->getInstalls(), $data['installs']);
262
        $this->assertSame($appDetail->getNumberVoters(), $data['numberVoters']);
263
        $this->assertSame($appDetail->getHistogramRating(), $data['histogramRating']);
264
265
        $this->assertSame(
266
            $appDetail->getHistogramRating()->__toString(),
267
            "⭐⭐⭐⭐⭐ {$appDetail->getHistogramRating()->getFiveStars()}\n" .
268
            "⭐⭐⭐⭐  {$appDetail->getHistogramRating()->getFourStars()}\n" .
269
            "⭐⭐⭐   {$appDetail->getHistogramRating()->getThreeStars()}\n" .
270
            "⭐⭐    {$appDetail->getHistogramRating()->getTwoStars()}\n" .
271
            "⭐     {$appDetail->getHistogramRating()->getOneStar()}"
272
        );
273
274
        $this->assertSame($appDetail->getPrice(), $data['price']);
275
        $this->assertSame($appDetail->getCurrency(), $data['currency']);
276
        $this->assertSame($appDetail->getPriceText(), $data['priceTextEur']);
277
        $this->assertSame($appDetail->getOffersIAPCost(), $data['offersIAPCost']);
278
        $this->assertTrue($appDetail->isOffersIAP());
279
        $this->assertTrue($appDetail->isAdSupported());
280
        $this->assertSame($appDetail->getAppSize(), $data['appSize']);
281
        $this->assertSame($appDetail->getAppVersion(), $data['appVersion']);
282
        $this->assertSame($appDetail->getAndroidVersion(), $data['androidVersion']);
283
        $this->assertSame($appDetail->getMinAndroidVersion(), $data['minAndroidVersion']);
284
        $this->assertSame($appDetail->getContentRating(), $data['contentRating']);
285
        $this->assertSame($appDetail->getReleased(), $data['released']);
286
        $this->assertSame($appDetail->getUpdated(), $data['updated']);
287
        $this->assertSame($appDetail->getReviewsCount(), $data['reviewsCount']);
288
        $this->assertSame($appDetail->getReviews(), $data['reviews']);
289
    }
290
291
    /**
292
     * @return array
293
     * @throws \Exception
294
     */
295
    public function provideAppBuilderData(): array
296
    {
297
        return [
298
            [
299
                [
300
                    'appId' => 'com.test',
301
                    'appUrl' => 'https://play.google.com/store/apps/details?id=com.test',
302
                    'appName' => 'Test',
303
                    'iconUrl' => 'https://lh3.googleusercontent.com/DKoidc0T3T1KvYC2stChcX9zwmjKj1pgmg3hXzGBDQXM8RG_7JjgiuS0CLOh8DUa7as=s180',
304
                    'developerId' => '11111111111',
305
                    'developerUrl' => 'https://play.google.com/store/apps/dev?id=11111111111',
306
                    'developerName' => 'Test Developer',
307
                    'developerEmail' => '[email protected]',
308
                    'developerSite' => 'https://example.com',
309
                    'developerAddress' => 'Test Address',
310
                    'summary' => 'tested application',
311
                    'score' => 4.235324,
312
                    'priceText' => '$0.99',
313
                    'locale' => 'en_US',
314
                    'description' => 'Description du test',
315
                    'screenshots' => [
316
                        new GoogleImage('https://lh3.ggpht.com/ueLFEoDXfL5ng9SeWLqstSw4GLAXyLgDSym5JKykOHpv_s0sm2HHHI_d2dAC_ugDyw=w720-h310'),
317
                        new GoogleImage('https://lh3.ggpht.com/bhb0uFArLTzGg515ayV_eOYNlgtmDkwQjhTmQIfK1r_U0nS7fOp2Xfz6dpLGQCUcPOHt=w720-h310'),
318
                        new GoogleImage('https://lh3.ggpht.com/pHNFX1g4E3QTnytKFOry-8rbaOMR9P8nT4IiuBZVYMHjfJLOYFsKSGvvTr_92SXafzU=w720-h310'),
319
                    ],
320
                    'categoryId' => 'EVENTS',
321
                    'categoryName' => 'Events',
322
                    'released' => new \DateTimeImmutable(
323
                        '-33 months',
324
                        new \DateTimeZone('UTC')
325
                    ),
326
                    'translatedDescription' => 'Test description',
327
                    'translatedFromLanguage' => 'fr_FR',
328
                    'headerImage' => new GoogleImage('https://lh3.googleusercontent.com/_X0MDs89e-vT-xHIfPWnx3ws1brEhC8v1cx3cuwubc9EYDIav3h2ickpUJJfWm1UBqg'),
329
                    'privacyPoliceUrl' => 'https://www.example.com/privacy.html',
330
                    'categoryFamilyId' => 'FAMILY_CREATE',
331
                    'categoryFamilyName' => 'Creativity',
332
                    'youtubeId' => 'Rz00UQ3dQyE',
333
                    'videoThumbUrl' => 'https://i.ytimg.com/vi/Rz00UQ3dQyE/hqdefault.jpg',
334
                    'videoUrl' => 'https://www.youtube.com/embed/Rz00UQ3dQyE?ps=play&vq=large&rel=0&autohide=1&showinfo=0',
335
                    'recentChanges' => 'Bug fixes',
336
                    'editorChoice' => true,
337
                    'installs' => 37539148,
338
                    'numberVoters' => 543269,
339
                    'histogramRating' => new HistogramRating(
340
                        285734,
341
                        170923,
342
                        47321,
343
                        13503,
344
                        25788
345
                    ),
346
                    'price' => 0.99,
347
                    'currency' => 'EUR',
348
                    'priceTextEur' => '€0.99',
349
                    'offersIAPCost' => '€1.89 per item',
350
                    'adSupported' => true,
351
                    'appSize' => '7.4M',
352
                    'appVersion' => '1.0.2',
353
                    'androidVersion' => '4.1 and up',
354
                    'minAndroidVersion' => '4.1',
355
                    'contentRating' => 'PEGI 3',
356
                    'updated' => new \DateTimeImmutable(
357
                        '-3 days 30 min',
358
                        new \DateTimeZone('UTC')
359
                    ),
360
                    'reviewsCount' => 15266,
361
                    'reviews' => [
362
                        new Review(
363
                            'gp:XXXXXXXXXXX',
364
                            'https://play.google.com/store/apps/details?id=com.test&hl=en_US&reviewId=gp:XXXXXXXXXXX',
365
                            'Google User',
366
                            'The best app!',
367
                            new GoogleImage('https://lh5.googleusercontent.com/-hGyaot6je8A/AAAAAAAAAAI/AAAAAAAAAAA/ACHi3rcSBa3olHGF7huPpQN97OQA01cmTQ/w200/avatar.jpg'),
368
                            new \DateTimeImmutable('2019-04-27 00:00:00.000000'),
369
                            4,
370
                            1,
371
                            new ReplyReview(
372
                                new \DateTimeImmutable('2019-04-28 00:00:00.000000'),
373
                                'Thanks!'
374
375
                            )
376
                        ),
377
                        new Review(
378
                            'gp:YYYYYYYYYYYYY',
379
                            'https://play.google.com/store/apps/details?id=com.test&hl=en_US&reviewId=gp:YYYYYYYYYYYYY',
380
                            'Google User',
381
                            'This app requires way too many permissions. The app requires access to your app history, web browsing history, and every other permission available just to make a phone call.',
382
                            new GoogleImage('https://lh4.googleusercontent.com/-l2Ebb1iCsto/AAAAAAAAAAI/AAAAAAAAAAA/ACHi3rd_fPyE4q23MdG95wvDs4_XJ27z6g/'),
383
                            new \DateTimeImmutable('2019-04-25 04:32:01.000000'),
384
                            2,
385
                            1514
386
                        ),
387
                    ],
388
                ],
389
            ],
390
        ];
391
    }
392
393
394
    public function testAppDetailEquals(): void
395
    {
396
        $builder = AppDetail::newBuilder()
397
            ->setId('com.test')
398
            ->setName('test')
399
            ->setLocale('en_US')
400
            ->setDeveloper(new Developer(
401
                Developer::newBuilder()
402
                    ->setId('010101101010')
403
                    ->setName('developer test')
404
                    ->setUrl('https://example.com/')
405
            ))
406
            ->setIcon(new GoogleImage('https://lh3.googleusercontent.com/DKoidc0T3T1KvYC2stChcX9zwmjKj1pgmg3hXzGBDQXM8RG_7JjgiuS0CLOh8DUa7as=s180'))
407
            ->setDescription('test description')
408
            ->addScreenshot(new GoogleImage('https://lh3.googleusercontent.com/1Ec6E-6nPcTn6OYzH9_P8sKupUsfJhbUd8M-iEOkzimaMr9CALI-KUpT2UyxHQUOPSY=w720-h310'))
409
            ->setCategory(new Category(
410
                'TEST',
411
                'Test Category'
412
            ));
413
414
        $builder2 = clone $builder;
415
416
        $appDetail = new AppDetail($builder);
417
        $appDetail2 = new AppDetail($builder2);
418
        $this->assertEquals($appDetail2, $appDetail);
419
        $this->assertTrue($appDetail->equals($appDetail2));
420
421
        $builder2->setIcon(new GoogleImage('https://lh3.googleusercontent.com/v0e5DxXFtAlnNzdxgpEd6tcS5r6sKxd1oswufLlQFuqOmMjGAukJXrUN5RtHabg69A=s180'));
422
        $appDetail2 = new AppDetail($builder2);
423
        $this->assertNotEquals($appDetail2, $appDetail);
424
        $this->assertFalse($appDetail->equals($appDetail2));
425
    }
426
}
427