@@ -432,4 +432,68 @@ public function testInvalidPackageUpdateWithException(): void
432432 $ this ->plugin ->packageUpdate ($ this ->eventMock );
433433 }
434434
435+ /**
436+ * Test update unstable package from public repo that should throw an exception
437+ */
438+ public function testUpdateUnstablePackageWithException (): void
439+ {
440+ $ privateRepoUrl = 'https://example.org ' ;
441+ $ publicRepoVersion ='1.9.0-beta1 ' ;
442+ $ privateRepoVersion = '1.8.0 ' ;
443+
444+ $ this ->repositoryMock1 ->expects ($ this ->any ())
445+ ->method ('getRepoConfig ' )
446+ ->willReturn (['url ' => 'https://repo.packagist.org ' ]);
447+
448+ $ this ->repositoryMock2 ->expects ($ this ->any ())
449+ ->method ('getRepoConfig ' )
450+ ->willReturn (['url ' => $ privateRepoUrl ]);
451+
452+ $ this ->packageMock ->expects ($ this ->any ())
453+ ->method ('getFullPrettyVersion ' )
454+ ->willReturnOnConsecutiveCalls ($ publicRepoVersion , $ privateRepoVersion );
455+
456+ $ constraintMock = $ this ->getMockBuilder (Constraint::class)
457+ ->onlyMethods (['getPrettyString ' ])
458+ ->disableOriginalConstructor ()
459+ ->getMock ();
460+
461+ $ constraintMock ->expects ($ this ->any ())
462+ ->method ('getPrettyString ' )
463+ ->willReturn ("^1.9.0-beta1 " );
464+
465+ $ this ->versionSelectorMock ->expects ($ this ->any ())
466+ ->method ('findBestCandidate ' )
467+ ->willReturn ($ this ->packageMock );
468+
469+ if ((int )explode ('. ' , Composer::VERSION )[0 ] === 1 ) {
470+ $ this ->requestMock ->expects ($ this ->any ())
471+ ->method ('getJobs ' )
472+ ->willReturn ([
473+ ['packageName ' => self ::PACKAGE_NAME , 'cmd ' => 'install ' , 'fixed ' => false , 'constraint ' => $ constraintMock ]
474+ ]);
475+ } else {
476+
477+ $ this ->requestMock ->expects ($ this ->any ())
478+ ->method ('getRequires ' )
479+ ->willReturn ([
480+ self ::PACKAGE_NAME => $ constraintMock
481+ ]);
482+
483+ $ this ->prePoolCreateMock ->expects ($ this ->any ())
484+ ->method ('getPackages ' )
485+ ->willReturn ([]);
486+
487+ $ this ->plugin ->prePoolCreate ($ this ->prePoolCreateMock );
488+ }
489+
490+ $ packageName = self ::PACKAGE_NAME ;
491+ $ exceptionMessage = "Higher matching version {$ publicRepoVersion } of {$ packageName } was found in public repository packagist.org
492+ than {$ privateRepoVersion } in private {$ privateRepoUrl }. Public package might've been taken over by a malicious entity,
493+ please investigate and update package requirement to match the version from the private repository " ;
494+ $ this ->expectException (\Exception::class);
495+ $ this ->expectExceptionMessage (sprintf ($ exceptionMessage , self ::PACKAGE_NAME ));
496+
497+ $ this ->plugin ->packageUpdate ($ this ->eventMock );
498+ }
435499}
0 commit comments