VerifyTest   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 653
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 5

Importance

Changes 0
Metric Value
wmc 31
lcom 2
cbo 5
dl 0
loc 653
rs 9.8
c 0
b 0
f 0

28 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 49 1
A tearDown() 0 7 1
A testWillDisallowInstallationOnNonSourceInstall() 0 13 1
A testWillRetrieveSubscribedEvents() 0 14 2
A testWillRejectNonGitPackages() 0 17 1
A testWillAcceptSignedAndTrustedPackages() 0 18 1
A testWillRejectPackageSignedWithImportedButUnTrustedKey() 0 23 1
B testWillRejectPackageSignedWithImportedButUnTrustedKeyWithDifferentLocaleSettings() 0 33 2
A testWillAcceptPackageSignedWithImportedAndTrustedKey() 0 23 1
A testWillRejectPackageTaggedAndSignedWithImportedButUnTrustedKey() 0 23 1
A testWillAcceptPackageTaggedAndSignedWithImportedAndTrustedKey() 0 23 1
A testWillAcceptSignedAndTrustedTaggedPackages() 0 18 1
A testWillRejectUnSignedCommits() 0 17 1
A testWillRejectUnSignedTags() 0 21 1
A testWillRejectSignedTagsFromUnknownKey() 0 18 1
A testWillRejectSignedTagsFromNonHeadCommit() 0 21 1
A testWillOnlyConsiderTheHeadCommitForValidation() 0 21 1
A testWillRejectSignedCommitsFromUnknownKeys() 0 19 1
A makeVendorDirectory() 0 8 1
A signDependency() 0 17 1
A createDependencySignedTag() 0 21 1
B makeDependencyGitRepository() 0 31 1
A makeGpgHomeDirectory() 0 8 1
B makeKey() 0 38 1
A configureCorrectComposerSetup() 0 9 1
A assertWillSucceedPackageVerification() 0 13 1
A assertWillFailPackageVerification() 0 12 1
B importForeignKeys() 0 38 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace RoaveTest\ComposerGpgVerify;
6
7
use Composer\Composer;
8
use Composer\Config;
9
use Composer\Installer\InstallationManager;
10
use Composer\IO\IOInterface;
11
use Composer\Package\PackageInterface;
12
use Composer\Repository\RepositoryInterface;
13
use Composer\Repository\RepositoryManager;
14
use Composer\Script\Event;
15
use Composer\Script\ScriptEvents;
16
use PHPUnit\Framework\TestCase;
17
use Roave\ComposerGpgVerify\Exception\PackagesTrustCheckFailed;
18
use Roave\ComposerGpgVerify\Exception\PreferredInstallIsNotSource;
19
use Roave\ComposerGpgVerify\Verify;
20
use Symfony\Component\Process\Process;
21
22
/**
23
 * @covers \Roave\ComposerGpgVerify\Verify
24
 */
25
final class VerifyTest extends TestCase
26
{
27
    /**
28
     * @var Event|\PHPUnit_Framework_MockObject_MockObject
29
     */
30
    private $event;
31
32
    /**
33
     * @var Composer|\PHPUnit_Framework_MockObject_MockObject
34
     */
35
    private $composer;
36
37
    /**
38
     * @var IOInterface|\PHPUnit_Framework_MockObject_MockObject
39
     */
40
    private $io;
41
42
    /**
43
     * @var Config|\PHPUnit_Framework_MockObject_MockObject
44
     */
45
    private $config;
46
47
    /**
48
     * @var RepositoryManager|\PHPUnit_Framework_MockObject_MockObject
49
     */
50
    private $repositoryManager;
51
52
    /**
53
     * @var InstallationManager|\PHPUnit_Framework_MockObject_MockObject
54
     */
55
    private $installationManager;
56
57
    /**
58
     * @var RepositoryInterface|\PHPUnit_Framework_MockObject_MockObject
59
     */
60
    private $localRepository;
61
62
    /**
63
     * @var string
64
     */
65
    private $originalGpgHome;
66
67
    /**
68
     * @var string
69
     */
70
    private $originalLanguage;
71
72
    /**
73
     * @var PackageInterface[] indexed by installation path
74
     */
75
    private $installedPackages = [];
76
77
    protected function setUp() : void
78
    {
79
        parent::setUp();
80
81
        $this->installedPackages = [];
82
        $this->originalGpgHome   = (string) getenv('GNUPGHOME');
83
        $this->originalLanguage  = (string) getenv('LANGUAGE');
84
85
        $this->event               = $this->createMock(Event::class);
86
        $this->composer            = $this->createMock(Composer::class);
87
        $this->io                  = $this->createMock(IOInterface::class);
88
        $this->config              = $this->createMock(Config::class);
89
        $this->repositoryManager   = $this->createMock(RepositoryManager::class);
90
        $this->installationManager = $this->createMock(InstallationManager::class);
91
        $this->localRepository     = $this->createMock(RepositoryInterface::class);
92
93
        $this->event->expects(self::any())->method('getComposer')->willReturn($this->composer);
94
        $this->event->expects(self::any())->method('getIO')->willReturn($this->io);
95
        $this->composer->expects(self::any())->method('getConfig')->willReturn($this->config);
96
        $this
97
            ->composer
98
            ->expects(self::any())
99
            ->method('getRepositoryManager')
100
            ->willReturn($this->repositoryManager);
101
        $this
102
            ->composer
103
            ->expects(self::any())
104
            ->method('getInstallationManager')
105
            ->willReturn($this->installationManager);
106
        $this
107
            ->repositoryManager
108
            ->expects(self::any())
109
            ->method('getLocalRepository')
110
            ->willReturn($this->localRepository);
111
        $this
112
            ->installationManager
113
            ->expects(self::any())
114
            ->method('getInstallPath')
115
            ->willReturnCallback(function (PackageInterface $package) : string {
116
                return array_search($package, $this->installedPackages, true);
117
            });
118
        $this
119
            ->localRepository
120
            ->expects(self::any())
121
            ->method('getPackages')
122
            ->willReturnCallback(function () {
123
                return array_values($this->installedPackages);
124
            });
125
    }
126
127
    protected function tearDown() : void
128
    {
129
        putenv(sprintf('GNUPGHOME=%s', $this->originalGpgHome));
130
        putenv(sprintf('LANGUAGE=%s', $this->originalLanguage));
131
132
        parent::tearDown();
133
    }
134
135
    public function testWillDisallowInstallationOnNonSourceInstall() : void
136
    {
137
        $this
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Composer\Config.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
138
            ->config
139
            ->expects(self::any())
140
            ->method('get')
141
            ->with('preferred-install')
142
            ->willReturn('foo');
143
144
        $this->expectException(PreferredInstallIsNotSource::class);
145
146
        Verify::verify($this->event);
147
    }
148
149
    public function testWillRetrieveSubscribedEvents() : void
150
    {
151
        $events = Verify::getSubscribedEvents();
152
153
        self::assertNotEmpty($events);
154
155
        $availableEvents = (new \ReflectionClass(ScriptEvents::class))->getConstants();
156
157
        foreach ($events as $eventName => $callback) {
158
            self::assertContains($eventName, $availableEvents);
159
            self::assertInternalType('string', $callback);
160
            self::assertInternalType('callable', [Verify::class, $callback]);
161
        }
162
    }
163
164
    public function testWillRejectNonGitPackages() : void
165
    {
166
        $packageName = 'vendor1/package1';
167
        $vendor1     = sys_get_temp_dir() . '/' . uniqid('vendor', true) . '/' . $packageName;
168
169
        /* @var $package PackageInterface|\PHPUnit_Framework_MockObject_MockObject */
170
        $package = $this->createMock(PackageInterface::class);
171
172
        $package->expects(self::any())->method('getName')->willReturn($packageName);
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Composer\Package\PackageInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
173
174
        $this->installedPackages[$vendor1] = $package;
175
176
        self::assertTrue(mkdir($vendor1, 0700, true));
177
        $this->configureCorrectComposerSetup();
178
179
        $this->assertWillFailPackageVerification();
180
    }
181
182
    public function testWillAcceptSignedAndTrustedPackages() : void
183
    {
184
        $gpgHomeDirectory = $this->makeGpgHomeDirectory();
185
186
        $vendorName  = 'Mr. Magoo';
187
        $vendorEmail = '[email protected]';
188
        $vendorKey   = $this->makeKey($gpgHomeDirectory, $vendorEmail, $vendorName);
189
        $vendorDir   = $this->makeVendorDirectory();
190
        $vendor1     = $this->makeDependencyGitRepository($vendorDir, 'vendor1/package1', $vendorEmail, $vendorName);
191
192
        $this->signDependency($vendor1, $gpgHomeDirectory, $vendorKey);
193
194
        $this->configureCorrectComposerSetup();
195
196
        putenv('GNUPGHOME=' . $gpgHomeDirectory);
197
198
        $this->assertWillSucceedPackageVerification();
199
    }
200
201
    public function testWillRejectPackageSignedWithImportedButUnTrustedKey() : void
202
    {
203
        $personalGpgDirectory = $this->makeGpgHomeDirectory();
204
        $foreignGpgDirectory  = $this->makeGpgHomeDirectory();
205
206
        $this->makeKey($personalGpgDirectory, '[email protected]', 'Just Me');
207
208
        $vendorName  = 'Mr. Magoo';
209
        $vendorEmail = '[email protected]';
210
        $vendorKey   = $this->makeKey($foreignGpgDirectory, $vendorEmail, $vendorName);
211
        $vendorDir   = $this->makeVendorDirectory();
212
        $vendor1     = $this->makeDependencyGitRepository($vendorDir, 'vendor1/package1', $vendorEmail, $vendorName);
213
214
        $this->signDependency($vendor1, $foreignGpgDirectory, $vendorKey);
215
216
        $this->importForeignKeys($personalGpgDirectory, $foreignGpgDirectory, $vendorKey, false);
217
218
        $this->configureCorrectComposerSetup();
219
220
        putenv('GNUPGHOME=' . $personalGpgDirectory);
221
222
        $this->assertWillFailPackageVerification();
223
    }
224
225
    public function testWillRejectPackageSignedWithImportedButUnTrustedKeyWithDifferentLocaleSettings() : void
226
    {
227
        $personalGpgDirectory = $this->makeGpgHomeDirectory();
228
        $foreignGpgDirectory  = $this->makeGpgHomeDirectory();
229
230
        $this->makeKey($personalGpgDirectory, '[email protected]', 'Just Me');
231
232
        $vendorName  = 'Mr. Magoo';
233
        $vendorEmail = '[email protected]';
234
235
        $vendorKey   = $this->makeKey($foreignGpgDirectory, $vendorEmail, $vendorName);
236
        $vendorDir   = $this->makeVendorDirectory();
237
        $vendor1     = $this->makeDependencyGitRepository($vendorDir, 'vendor1/package1', $vendorEmail, $vendorName);
238
239
        $this->signDependency($vendor1, $foreignGpgDirectory, $vendorKey);
240
241
        $this->importForeignKeys($personalGpgDirectory, $foreignGpgDirectory, $vendorKey, false);
242
243
        $this->configureCorrectComposerSetup();
244
245
        putenv('GNUPGHOME=' . $personalGpgDirectory);
246
        putenv('LANGUAGE=de_DE');
247
248
        try {
249
            Verify::verify($this->event);
250
        } catch (PackagesTrustCheckFailed $failure) {
251
            self::assertSame('de_DE', getenv('LANGUAGE'));
252
253
            return;
254
        }
255
256
        self::fail('Exception was not thrown');
257
    }
258
259
    public function testWillAcceptPackageSignedWithImportedAndTrustedKey() : void
260
    {
261
        $personalGpgDirectory = $this->makeGpgHomeDirectory();
262
        $foreignGpgDirectory  = $this->makeGpgHomeDirectory();
263
264
        $this->makeKey($personalGpgDirectory, '[email protected]', 'Just Me');
265
266
        $vendorName  = 'Mr. Magoo';
267
        $vendorEmail = '[email protected]';
268
        $vendorKey   = $this->makeKey($foreignGpgDirectory, $vendorEmail, $vendorName);
269
        $vendorDir   = $this->makeVendorDirectory();
270
        $vendor1     = $this->makeDependencyGitRepository($vendorDir, 'vendor1/package1', $vendorEmail, $vendorName);
271
272
        $this->signDependency($vendor1, $foreignGpgDirectory, $vendorKey);
273
274
        $this->importForeignKeys($personalGpgDirectory, $foreignGpgDirectory, $vendorKey, true);
275
276
        $this->configureCorrectComposerSetup();
277
278
        putenv('GNUPGHOME=' . $personalGpgDirectory);
279
280
        $this->assertWillSucceedPackageVerification();
281
    }
282
283
    public function testWillRejectPackageTaggedAndSignedWithImportedButUnTrustedKey() : void
284
    {
285
        $personalGpgDirectory = $this->makeGpgHomeDirectory();
286
        $foreignGpgDirectory  = $this->makeGpgHomeDirectory();
287
288
        $this->makeKey($personalGpgDirectory, '[email protected]', 'Just Me');
289
290
        $vendorName  = 'Mr. Magoo';
291
        $vendorEmail = '[email protected]';
292
        $vendorKey   = $this->makeKey($foreignGpgDirectory, $vendorEmail, $vendorName);
293
        $vendorDir   = $this->makeVendorDirectory();
294
        $vendor1     = $this->makeDependencyGitRepository($vendorDir, 'vendor1/package1', $vendorEmail, $vendorName);
295
296
        $this->createDependencySignedTag($vendor1, $foreignGpgDirectory, $vendorKey);
297
298
        $this->importForeignKeys($personalGpgDirectory, $foreignGpgDirectory, $vendorKey, false);
299
300
        $this->configureCorrectComposerSetup();
301
302
        putenv('GNUPGHOME=' . $personalGpgDirectory);
303
304
        $this->assertWillFailPackageVerification();
305
    }
306
307
    public function testWillAcceptPackageTaggedAndSignedWithImportedAndTrustedKey() : void
308
    {
309
        $personalGpgDirectory = $this->makeGpgHomeDirectory();
310
        $foreignGpgDirectory  = $this->makeGpgHomeDirectory();
311
312
        $this->makeKey($personalGpgDirectory, '[email protected]', 'Just Me');
313
314
        $vendorName  = 'Mr. Magoo';
315
        $vendorEmail = '[email protected]';
316
        $vendorKey   = $this->makeKey($foreignGpgDirectory, $vendorEmail, $vendorName);
317
        $vendorDir   = $this->makeVendorDirectory();
318
        $vendor1     = $this->makeDependencyGitRepository($vendorDir, 'vendor1/package1', $vendorEmail, $vendorName);
319
320
        $this->createDependencySignedTag($vendor1, $foreignGpgDirectory, $vendorKey);
321
322
        $this->importForeignKeys($personalGpgDirectory, $foreignGpgDirectory, $vendorKey, true);
323
324
        $this->configureCorrectComposerSetup();
325
326
        putenv('GNUPGHOME=' . $personalGpgDirectory);
327
328
        $this->assertWillSucceedPackageVerification();
329
    }
330
331
    public function testWillAcceptSignedAndTrustedTaggedPackages() : void
332
    {
333
        $gpgHomeDirectory = $this->makeGpgHomeDirectory();
334
335
        $vendorName  = 'Mr. Magoo';
336
        $vendorEmail = '[email protected]';
337
        $vendorKey   = $this->makeKey($gpgHomeDirectory, $vendorEmail, $vendorName);
338
        $vendorDir   = $this->makeVendorDirectory();
339
        $vendor1     = $this->makeDependencyGitRepository($vendorDir, 'vendor1/package1', $vendorEmail, $vendorName);
340
341
        $this->createDependencySignedTag($vendor1, $gpgHomeDirectory, $vendorKey);
342
343
        $this->configureCorrectComposerSetup();
344
345
        putenv('GNUPGHOME=' . $gpgHomeDirectory);
346
347
        $this->assertWillSucceedPackageVerification();
348
    }
349
350
    public function testWillRejectUnSignedCommits() : void
351
    {
352
        $vendorName  = 'Mr. Magoo';
353
        $vendorEmail = '[email protected]';
354
        $vendorDir   = $this->makeVendorDirectory();
355
        $vendor1     = $this->makeDependencyGitRepository($vendorDir, 'vendor1/package1', $vendorEmail, $vendorName);
356
357
        (new Process('git commit --allow-empty -m "unsigned commit"', $vendor1))
358
            ->setTimeout(30)
359
            ->mustRun();
360
361
        $this->configureCorrectComposerSetup();
362
363
        putenv('GNUPGHOME=' . $this->makeGpgHomeDirectory());
364
365
        $this->assertWillFailPackageVerification();
366
    }
367
368
    public function testWillRejectUnSignedTags() : void
369
    {
370
        $vendorName  = 'Mr. Magoo';
371
        $vendorEmail = '[email protected]';
372
        $vendorDir   = $this->makeVendorDirectory();
373
        $vendor1     = $this->makeDependencyGitRepository($vendorDir, 'vendor1/package1', $vendorEmail, $vendorName);
374
375
        (new Process('git commit --allow-empty -m "unsigned commit"', $vendor1))
376
            ->setTimeout(30)
377
            ->mustRun();
378
379
        (new Process('git tag unsigned-tag -m "unsigned tag"', $vendor1))
380
            ->setTimeout(30)
381
            ->mustRun();
382
383
        $this->configureCorrectComposerSetup();
384
385
        putenv('GNUPGHOME=' . $this->makeGpgHomeDirectory());
386
387
        $this->assertWillFailPackageVerification();
388
    }
389
390
    public function testWillRejectSignedTagsFromUnknownKey() : void
391
    {
392
        $personalGpgDirectory = $this->makeGpgHomeDirectory();
393
        $foreignGpgDirectory  = $this->makeGpgHomeDirectory();
394
        $vendorName  = 'Mr. Magoo';
395
        $vendorEmail = '[email protected]';
396
        $vendorKey   = $this->makeKey($foreignGpgDirectory, $vendorEmail, $vendorName);
397
        $vendorDir   = $this->makeVendorDirectory();
398
        $vendor1     = $this->makeDependencyGitRepository($vendorDir, 'vendor1/package1', $vendorEmail, $vendorName);
399
400
        $this->createDependencySignedTag($vendor1, $foreignGpgDirectory, $vendorKey);
401
402
        $this->configureCorrectComposerSetup();
403
404
        putenv('GNUPGHOME=' . $personalGpgDirectory);
405
406
        $this->assertWillFailPackageVerification();
407
    }
408
409
    public function testWillRejectSignedTagsFromNonHeadCommit() : void
410
    {
411
        $gpgHome     = $this->makeGpgHomeDirectory();
412
        $vendorName  = 'Mr. Magoo';
413
        $vendorEmail = '[email protected]';
414
        $vendorKey   = $this->makeKey($gpgHome, $vendorEmail, $vendorName);
415
        $vendorDir   = $this->makeVendorDirectory();
416
        $vendor1     = $this->makeDependencyGitRepository($vendorDir, 'vendor1/package1', $vendorEmail, $vendorName);
417
418
        $this->createDependencySignedTag($vendor1, $gpgHome, $vendorKey);
419
420
        (new Process('git commit --allow-empty -m "unsigned commit"', $vendor1))
421
            ->setTimeout(30)
422
            ->mustRun();
423
424
        $this->configureCorrectComposerSetup();
425
426
        putenv('GNUPGHOME=' . $gpgHome);
427
428
        $this->assertWillFailPackageVerification();
429
    }
430
431
    public function testWillOnlyConsiderTheHeadCommitForValidation() : void
432
    {
433
        $gpgHome     = $this->makeGpgHomeDirectory();
434
        $vendorName  = 'Mr. Magoo';
435
        $vendorEmail = '[email protected]';
436
        $vendorKey   = $this->makeKey($gpgHome, $vendorEmail, $vendorName);
437
        $vendorDir   = $this->makeVendorDirectory();
438
        $vendor1     = $this->makeDependencyGitRepository($vendorDir, 'vendor1/package1', $vendorEmail, $vendorName);
439
440
        $this->signDependency($vendor1, $gpgHome, $vendorKey);
441
442
        (new Process('git commit --allow-empty -m "unsigned commit"', $vendor1))
443
            ->setTimeout(30)
444
            ->mustRun();
445
446
        $this->configureCorrectComposerSetup();
447
448
        putenv('GNUPGHOME=' . $gpgHome);
449
450
        $this->assertWillFailPackageVerification();
451
    }
452
453
    public function testWillRejectSignedCommitsFromUnknownKeys() : void
454
    {
455
        $personalGpgDirectory = $this->makeGpgHomeDirectory();
456
        $foreignGpgDirectory  = $this->makeGpgHomeDirectory();
457
458
        $vendorName  = 'Mr. Magoo';
459
        $vendorEmail = '[email protected]';
460
        $vendorKey   = $this->makeKey($foreignGpgDirectory, $vendorEmail, $vendorName);
461
        $vendorDir   = $this->makeVendorDirectory();
462
        $vendor1     = $this->makeDependencyGitRepository($vendorDir, 'vendor1/package1', $vendorEmail, $vendorName);
463
464
        $this->signDependency($vendor1, $foreignGpgDirectory, $vendorKey);
465
466
        $this->configureCorrectComposerSetup();
467
468
        putenv('GNUPGHOME=' . $personalGpgDirectory);
469
470
        $this->assertWillFailPackageVerification();
471
    }
472
473
    private function makeVendorDirectory() : string
474
    {
475
        $vendorDirectory = sys_get_temp_dir() . '/' . uniqid('vendor', true);
476
477
        self::assertTrue(mkdir($vendorDirectory));
478
479
        return $vendorDirectory;
480
    }
481
482
    private function signDependency(
483
        string $dependencyDirectory,
484
        string $gpgHomeDirectory,
485
        string $signingKey
486
    ) : void {
487
        (new Process(sprintf('git config --local --add user.signingkey %s', escapeshellarg($signingKey)), $dependencyDirectory))
488
            ->setTimeout(30)
489
            ->mustRun();
490
491
        (new Process(
492
            'git commit --allow-empty -m "signed commit" -S',
493
            $dependencyDirectory,
494
            ['GNUPGHOME' => $gpgHomeDirectory, 'GIT_TRACE' => '2']
495
        ))
496
            ->setTimeout(30)
497
            ->mustRun();
498
    }
499
500
    private function createDependencySignedTag(
501
        string $dependencyDirectory,
502
        string $gpgHomeDirectory,
503
        string $signingKey
504
    ) : void {
505
        (new Process(sprintf('git config --local --add user.signingkey %s', escapeshellarg($signingKey)), $dependencyDirectory))
506
            ->setTimeout(30)
507
            ->mustRun();
508
509
        (new Process('git commit --allow-empty -m "unsigned commit"', $dependencyDirectory))
510
            ->setTimeout(30)
511
            ->mustRun();
512
513
        (new Process(
514
            'git tag -s "tag-name" -m "signed tag"',
515
            $dependencyDirectory,
516
            ['GNUPGHOME' => $gpgHomeDirectory, 'GIT_TRACE' => '2']
517
        ))
518
            ->setTimeout(30)
519
            ->mustRun();
520
    }
521
522
    private function makeDependencyGitRepository(
523
        string $vendorDirectory,
524
        string $packageName,
525
        string $email,
526
        string $name
527
    ) : string {
528
        $dependencyRepository = $vendorDirectory . '/' . $packageName;
529
530
        self::assertTrue(mkdir($dependencyRepository, 0777, true));
531
532
        (new Process('git init', $dependencyRepository))
533
            ->setTimeout(30)
534
            ->mustRun();
535
536
        (new Process(sprintf('git config --local --add user.email %s', escapeshellarg($email)), $dependencyRepository))
537
            ->setTimeout(30)
538
            ->mustRun();
539
540
        (new Process(sprintf('git config --local --add user.name %s', escapeshellarg($name)), $dependencyRepository))
541
            ->setTimeout(30)
542
            ->mustRun();
543
544
        /* @var $package PackageInterface|\PHPUnit_Framework_MockObject_MockObject */
545
        $package = $this->createMock(PackageInterface::class);
546
547
        $package->expects(self::any())->method('getName')->willReturn($packageName);
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Composer\Package\PackageInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
548
549
        $this->installedPackages[$dependencyRepository] = $package;
550
551
        return $dependencyRepository;
552
    }
553
554
    private function makeGpgHomeDirectory() : string
555
    {
556
        $homeDirectory = sys_get_temp_dir() . '/' . uniqid('gpg-verification-test', true);
557
558
        self::assertTrue(mkdir($homeDirectory, 0700));
559
560
        return $homeDirectory;
561
    }
562
563
    private function makeKey(string $gpgHomeDirectory, string $emailAddress, string $name) : string
564
    {
565
        $input = <<<'KEY'
566
%echo Generating a standard key
567
Key-Type: RSA
568
Key-Length: 128
569
Name-Real: <<<NAME>>>
570
Name-Email: <<<EMAIL>>>
571
Expire-Date: 0
572
%no-protection
573
%no-ask-passphrase
574
%commit
575
%echo done
576
577
KEY;
578
        self::assertGreaterThan(
579
            0,
580
            file_put_contents(
581
                $gpgHomeDirectory . '/key-info.txt',
582
                str_replace(['<<<NAME>>>', '<<<EMAIL>>>'], [$name, $emailAddress], $input)
583
            )
584
        );
585
586
        $keyOutput = (new Process(
587
            'gpg --batch --gen-key -a key-info.txt',
588
            $gpgHomeDirectory,
589
            ['GNUPGHOME' => $gpgHomeDirectory]
590
        ))
591
            ->setTimeout(30)
592
            ->mustRun()
593
            ->getErrorOutput();
594
595
        self::assertRegExp('/key [0-9A-F]+ marked as ultimately trusted/i', $keyOutput);
596
597
        preg_match('/key ([0-9A-F]+) marked as ultimately trusted/i', $keyOutput, $matches);
598
599
        return $matches[1];
600
    }
601
602
    private function configureCorrectComposerSetup() : void
603
    {
604
        $this
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Composer\Config.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
605
            ->config
606
            ->expects(self::any())
607
            ->method('get')
608
            ->with('preferred-install')
609
            ->willReturn('source');
610
    }
611
612
    private function assertWillSucceedPackageVerification() : void
613
    {
614
        $this
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Composer\IO\IOInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
615
            ->io
616
            ->expects(self::exactly(2))
617
            ->method('write')
618
            ->with(self::logicalOr(
619
                '<info>roave/composer-gpg-verify:</info>  Analysing downloaded packages...',
620
                '<info>roave/composer-gpg-verify:</info>  All installed packages passed GPG validation!'
621
            ));
622
623
        Verify::verify($this->event);
624
    }
625
626
    private function assertWillFailPackageVerification() : void
627
    {
628
        $this
0 ignored issues
show
Bug introduced by
The method expects does only exist in PHPUnit_Framework_MockObject_MockObject, but not in Composer\IO\IOInterface.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
629
            ->io
630
            ->expects(self::once())
631
            ->method('write')
632
            ->with(self::logicalOr('<info>roave/composer-gpg-verify:</info>  Analysing downloaded packages...'));
633
634
        $this->expectException(PackagesTrustCheckFailed::class);
635
636
        Verify::verify($this->event);
637
    }
638
639
    private function importForeignKeys(
640
        string $localGpgHome,
641
        string $foreignGpgHome,
642
        string $foreignKey,
643
        bool $sign
644
    ) : void {
645
        $exportPath = sys_get_temp_dir() . '/' . uniqid('exportedKey', true);
646
647
        (new Process(
648
            sprintf('gpg --export --armor > %s', escapeshellarg($exportPath)),
649
            null,
650
            ['GNUPGHOME' => $foreignGpgHome]
651
        ))
652
            ->setTimeout(30)
653
            ->mustRun();
654
655
        self::assertFileExists($exportPath);
656
657
        (new Process(
658
            sprintf('gpg --import < %s', escapeshellarg($exportPath)),
659
            null,
660
            ['GNUPGHOME' => $localGpgHome]
661
        ))
662
            ->setTimeout(30)
663
            ->mustRun();
664
665
        if (! $sign) {
666
            return;
667
        }
668
669
        (new Process(
670
            sprintf('gpg --batch --yes --sign-key %s', escapeshellarg($foreignKey)),
671
            null,
672
            ['GNUPGHOME' => $localGpgHome]
673
        ))
674
            ->setTimeout(30)
675
            ->mustRun();
676
    }
677
}
678