diff options
author | Carl Schwan <carl@carlschwan.eu> | 2022-08-15 15:28:30 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-15 15:28:30 +0200 |
commit | 51b9847fad73a1ca67dbf504358d90bd8f9e71d8 (patch) | |
tree | b104cf1c540dd1dd195ca5fd30c42b888012cbab /tests | |
parent | 6d6662ec68c8e15c4c6bfdf1c694794badd412d7 (diff) | |
parent | cb97e8f15c75cc46e345ebfc79dcad1b9c48bd01 (diff) | |
download | nextcloud-server-51b9847fad73a1ca67dbf504358d90bd8f9e71d8.tar.gz nextcloud-server-51b9847fad73a1ca67dbf504358d90bd8f9e71d8.zip |
Merge branch 'master' into display-name-cache-public
Signed-off-by: Carl Schwan <carl@carlschwan.eu>
Diffstat (limited to 'tests')
79 files changed, 3826 insertions, 2220 deletions
diff --git a/tests/Core/Command/Preview/RepairTest.php b/tests/Core/Command/Preview/RepairTest.php index a6591745817..d235c0d0aea 100644 --- a/tests/Core/Command/Preview/RepairTest.php +++ b/tests/Core/Command/Preview/RepairTest.php @@ -8,20 +8,20 @@ use OCP\Files\Folder; use OCP\Files\IRootFolder; use OCP\Files\Node; use OCP\IConfig; -use OCP\ILogger; use OCP\Lock\ILockingProvider; use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\Console\Formatter\OutputFormatterInterface; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Test\TestCase; +use Psr\Log\LoggerInterface; class RepairTest extends TestCase { /** @var IConfig|MockObject */ private $config; /** @var IRootFolder|MockObject */ private $rootFolder; - /** @var ILogger|MockObject */ + /** @var LoggerInterface|MockObject */ private $logger; /** @var IniGetWrapper|MockObject */ private $iniGetWrapper; @@ -40,7 +40,7 @@ class RepairTest extends TestCase { ->getMock(); $this->rootFolder = $this->getMockBuilder(IRootFolder::class) ->getMock(); - $this->logger = $this->getMockBuilder(ILogger::class) + $this->logger = $this->getMockBuilder(LoggerInterface::class) ->getMock(); $this->iniGetWrapper = $this->getMockBuilder(IniGetWrapper::class) ->getMock(); diff --git a/tests/Core/Controller/AutoCompleteControllerTest.php b/tests/Core/Controller/AutoCompleteControllerTest.php index 0775fbbd818..6b2f9a4f163 100644 --- a/tests/Core/Controller/AutoCompleteControllerTest.php +++ b/tests/Core/Controller/AutoCompleteControllerTest.php @@ -171,15 +171,9 @@ class AutoCompleteControllerTest extends TestCase { } /** - * @param $searchResults - * @param $expected - * @param $searchTerm - * @param $itemType - * @param $itemId - * @param $sorter * @dataProvider searchDataProvider */ - public function testGet($searchResults, $expected, $searchTerm, $itemType, $itemId, $sorter) { + public function testGet(array $searchResults, array $expected, string $searchTerm, ?string $itemType, ?string $itemId, ?string $sorter) { $this->collaboratorSearch->expects($this->once()) ->method('search') ->willReturn([$searchResults, false]); diff --git a/tests/Core/Controller/AvatarControllerTest.php b/tests/Core/Controller/AvatarControllerTest.php index 8d3cd73a656..256f5665795 100644 --- a/tests/Core/Controller/AvatarControllerTest.php +++ b/tests/Core/Controller/AvatarControllerTest.php @@ -38,14 +38,15 @@ use OCP\Files\File; use OCP\Files\IRootFolder; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; +use OCP\Files\SimpleFS\ISimpleFile; use OCP\IAvatar; use OCP\IAvatarManager; use OCP\ICache; use OCP\IL10N; -use OCP\ILogger; use OCP\IRequest; use OCP\IUser; use OCP\IUserManager; +use Psr\Log\LoggerInterface; /** * Class AvatarControllerTest @@ -59,7 +60,7 @@ class AvatarControllerTest extends \Test\TestCase { private $avatarMock; /** @var IUser|\PHPUnit\Framework\MockObject\MockObject */ private $userMock; - /** @var File|\PHPUnit\Framework\MockObject\MockObject */ + /** @var ISimpleFile|\PHPUnit\Framework\MockObject\MockObject */ private $avatarFile; /** @var IAvatarManager|\PHPUnit\Framework\MockObject\MockObject */ @@ -72,7 +73,7 @@ class AvatarControllerTest extends \Test\TestCase { private $userManager; /** @var IRootFolder|\PHPUnit\Framework\MockObject\MockObject */ private $rootFolder; - /** @var ILogger|\PHPUnit\Framework\MockObject\MockObject */ + /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ private $logger; /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ private $request; @@ -90,7 +91,7 @@ class AvatarControllerTest extends \Test\TestCase { $this->userManager = $this->getMockBuilder(IUserManager::class)->getMock(); $this->request = $this->getMockBuilder(IRequest::class)->getMock(); $this->rootFolder = $this->getMockBuilder('OCP\Files\IRootFolder')->getMock(); - $this->logger = $this->getMockBuilder(ILogger::class)->getMock(); + $this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock(); $this->timeFactory = $this->getMockBuilder('OC\AppFramework\Utility\TimeFactory')->getMock(); $this->avatarMock = $this->getMockBuilder('OCP\IAvatar')->getMock(); @@ -115,7 +116,7 @@ class AvatarControllerTest extends \Test\TestCase { $this->userManager->method('get') ->willReturnMap([['userId', $this->userMock]]); - $this->avatarFile = $this->getMockBuilder('OCP\Files\File')->getMock(); + $this->avatarFile = $this->getMockBuilder(ISimpleFile::class)->getMock(); $this->avatarFile->method('getContent')->willReturn('image data'); $this->avatarFile->method('getMimeType')->willReturn('image type'); $this->avatarFile->method('getEtag')->willReturn('my etag'); @@ -293,8 +294,8 @@ class AvatarControllerTest extends \Test\TestCase { $this->avatarManager->method('getAvatar')->willReturn($this->avatarMock); $this->logger->expects($this->once()) - ->method('logException') - ->with(new \Exception("foo")); + ->method('error') + ->with('foo', ['exception' => new \Exception("foo"), 'app' => 'core']); $expectedResponse = new Http\JSONResponse(['data' => ['message' => 'An error occurred. Please contact your admin.']], Http::STATUS_BAD_REQUEST); $this->assertEquals($expectedResponse, $this->avatarController->deleteAvatar()); } @@ -485,8 +486,8 @@ class AvatarControllerTest extends \Test\TestCase { $userFolder->method('get')->willReturn($file); $this->logger->expects($this->once()) - ->method('logException') - ->with(new \Exception("foo")); + ->method('error') + ->with('foo', ['exception' => new \Exception("foo"), 'app' => 'core']); $expectedResponse = new Http\JSONResponse(['data' => ['message' => 'An error occurred. Please contact your admin.']], Http::STATUS_OK); $this->assertEquals($expectedResponse, $this->avatarController->postAvatar('avatar.jpg')); } @@ -545,8 +546,8 @@ class AvatarControllerTest extends \Test\TestCase { $this->avatarManager->method('getAvatar')->willReturn($this->avatarMock); $this->logger->expects($this->once()) - ->method('logException') - ->with(new \Exception('foo')); + ->method('error') + ->with('foo', ['exception' => new \Exception("foo"), 'app' => 'core']); $expectedResponse = new Http\JSONResponse(['data' => ['message' => 'An error occurred. Please contact your admin.']], Http::STATUS_BAD_REQUEST); $this->assertEquals($expectedResponse, $this->avatarController->postCroppedAvatar(['x' => 0, 'y' => 0, 'w' => 10, 'h' => 11])); } diff --git a/tests/Core/Controller/GuestAvatarControllerTest.php b/tests/Core/Controller/GuestAvatarControllerTest.php index b5682d2d716..8688f531519 100644 --- a/tests/Core/Controller/GuestAvatarControllerTest.php +++ b/tests/Core/Controller/GuestAvatarControllerTest.php @@ -7,8 +7,8 @@ use OCP\AppFramework\Http\FileDisplayResponse; use OCP\Files\SimpleFS\ISimpleFile; use OCP\IAvatar; use OCP\IAvatarManager; -use OCP\ILogger; use OCP\IRequest; +use Psr\Log\LoggerInterface; /** * This class provides tests for the guest avatar controller. @@ -41,7 +41,7 @@ class GuestAvatarControllerTest extends \Test\TestCase { private $file; /** - * @var ILogger|\PHPUnit\Framework\MockObject\MockObject + * @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ private $logger; @@ -51,7 +51,7 @@ class GuestAvatarControllerTest extends \Test\TestCase { protected function setUp(): void { parent::setUp(); - $this->logger = $this->getMockBuilder(ILogger::class)->getMock(); + $this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock(); $this->request = $this->getMockBuilder(IRequest::class)->getMock(); $this->avatar = $this->getMockBuilder(IAvatar::class)->getMock(); $this->avatarManager = $this->getMockBuilder(IAvatarManager::class)->getMock(); diff --git a/tests/Core/Controller/LoginControllerTest.php b/tests/Core/Controller/LoginControllerTest.php index 30a625a612b..cee3da65994 100644 --- a/tests/Core/Controller/LoginControllerTest.php +++ b/tests/Core/Controller/LoginControllerTest.php @@ -34,7 +34,6 @@ use OCP\Defaults; use OCP\IConfig; use OCP\IInitialStateService; use OCP\IL10N; -use OCP\ILogger; use OCP\IRequest; use OCP\ISession; use OCP\IURLGenerator; @@ -67,9 +66,6 @@ class LoginControllerTest extends TestCase { /** @var IURLGenerator|MockObject */ private $urlGenerator; - /** @var ILogger|MockObject */ - private $logger; - /** @var Manager|MockObject */ private $twoFactorManager; @@ -102,7 +98,6 @@ class LoginControllerTest extends TestCase { $this->session = $this->createMock(ISession::class); $this->userSession = $this->createMock(Session::class); $this->urlGenerator = $this->createMock(IURLGenerator::class); - $this->logger = $this->createMock(ILogger::class); $this->twoFactorManager = $this->createMock(Manager::class); $this->defaults = $this->createMock(Defaults::class); $this->throttler = $this->createMock(Throttler::class); @@ -134,7 +129,6 @@ class LoginControllerTest extends TestCase { $this->session, $this->userSession, $this->urlGenerator, - $this->logger, $this->defaults, $this->throttler, $this->chain, @@ -234,7 +228,7 @@ class LoginControllerTest extends TestCase { ->willReturn('/default/foo'); $expectedResponse = new RedirectResponse('/default/foo'); - $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('', '', '')); + $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('', '')); } public function testShowLoginFormWithErrorsInSession() { @@ -285,10 +279,11 @@ class LoginControllerTest extends TestCase { 'login', [ 'alt_login' => [], + 'pageTitle' => 'Login' ], 'guest' ); - $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('', '', '')); + $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('', '')); } public function testShowLoginFormForFlowAuth() { @@ -309,16 +304,17 @@ class LoginControllerTest extends TestCase { 'login', [ 'alt_login' => [], + 'pageTitle' => 'Login' ], 'guest' ); - $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('', 'login/flow', '')); + $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('', 'login/flow')); } /** * @return array */ - public function passwordResetDataProvider() { + public function passwordResetDataProvider(): array { return [ [ true, @@ -377,10 +373,11 @@ class LoginControllerTest extends TestCase { 'login', [ 'alt_login' => [], + 'pageTitle' => 'Login' ], 'guest' ); - $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('LdapUser', '', '')); + $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('LdapUser', '')); } public function testShowLoginFormForUserNamed0() { @@ -431,10 +428,11 @@ class LoginControllerTest extends TestCase { 'login', [ 'alt_login' => [], + 'pageTitle' => 'Login' ], 'guest' ); - $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('0', '', '')); + $this->assertEquals($expectedResponse, $this->loginController->showLoginForm('0', '')); } public function testLoginWithInvalidCredentials() { diff --git a/tests/Core/Controller/LostControllerTest.php b/tests/Core/Controller/LostControllerTest.php index e860c808014..31f2767ea4f 100644 --- a/tests/Core/Controller/LostControllerTest.php +++ b/tests/Core/Controller/LostControllerTest.php @@ -23,16 +23,18 @@ namespace Tests\Core\Controller; use OC\Authentication\TwoFactorAuth\Manager; use OC\Core\Controller\LostController; +use OC\Core\Events\BeforePasswordResetEvent; +use OC\Core\Events\PasswordResetEvent; use OC\Mail\Message; use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\TemplateResponse; +use OCP\AppFramework\Services\IInitialState; use OCP\Defaults; use OCP\Encryption\IEncryptionModule; use OCP\Encryption\IManager; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; -use OCP\IInitialStateService; use OCP\IL10N; -use OCP\ILogger; use OCP\IRequest; use OCP\IURLGenerator; use OCP\IUser; @@ -41,42 +43,45 @@ use OCP\Mail\IEMailTemplate; use OCP\Mail\IMailer; use OCP\Security\VerificationToken\InvalidTokenException; use OCP\Security\VerificationToken\IVerificationToken; +use Psr\Log\LoggerInterface; +use PHPUnit\Framework\MockObject\MockObject; +use Test\TestCase; /** * Class LostControllerTest * * @package OC\Core\Controller */ -class LostControllerTest extends \Test\TestCase { - - /** @var LostController */ - private $lostController; +class LostControllerTest extends TestCase { + private LostController $lostController; /** @var IUser */ private $existingUser; - /** @var IURLGenerator | \PHPUnit\Framework\MockObject\MockObject */ + /** @var IURLGenerator | MockObject */ private $urlGenerator; /** @var IL10N */ private $l10n; - /** @var IUserManager | \PHPUnit\Framework\MockObject\MockObject */ + /** @var IUserManager | MockObject */ private $userManager; /** @var Defaults */ private $defaults; - /** @var IConfig | \PHPUnit\Framework\MockObject\MockObject */ + /** @var IConfig | MockObject */ private $config; - /** @var IMailer | \PHPUnit\Framework\MockObject\MockObject */ + /** @var IMailer | MockObject */ private $mailer; - /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IManager|MockObject */ private $encryptionManager; - /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IRequest|MockObject */ private $request; - /** @var ILogger|\PHPUnit\Framework\MockObject\MockObject */ + /** @var LoggerInterface|MockObject */ private $logger; - /** @var Manager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var Manager|MockObject */ private $twofactorManager; - /** @var IInitialStateService|\PHPUnit\Framework\MockObject\MockObject */ - private $initialStateService; - /** @var IVerificationToken|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IInitialState|MockObject */ + private $initialState; + /** @var IVerificationToken|MockObject */ private $verificationToken; + /** @var IEventDispatcher|MockObject */ + private $eventDispatcher; protected function setUp(): void { parent::setUp(); @@ -110,25 +115,20 @@ class LostControllerTest extends \Test\TestCase { ->willReturnCallback(function ($text, $parameters = []) { return vsprintf($text, $parameters); }); - $this->defaults = $this->getMockBuilder('\OCP\Defaults') - ->disableOriginalConstructor()->getMock(); - $this->userManager = $this->getMockBuilder(IUserManager::class) - ->disableOriginalConstructor()->getMock(); - $this->urlGenerator = $this->getMockBuilder(IURLGenerator::class) - ->disableOriginalConstructor()->getMock(); - $this->mailer = $this->getMockBuilder('\OCP\Mail\IMailer') - ->disableOriginalConstructor()->getMock(); - $this->request = $this->getMockBuilder(IRequest::class) - ->disableOriginalConstructor()->getMock(); - $this->encryptionManager = $this->getMockBuilder(IManager::class) - ->disableOriginalConstructor()->getMock(); + $this->defaults = $this->createMock(Defaults::class); + $this->userManager = $this->createMock(IUserManager::class); + $this->urlGenerator = $this->createMock(IURLGenerator::class); + $this->mailer = $this->createMock(IMailer::class); + $this->request = $this->createMock(IRequest::class); + $this->encryptionManager = $this->createMock(IManager::class); $this->encryptionManager->expects($this->any()) ->method('isEnabled') ->willReturn(true); - $this->logger = $this->createMock(ILogger::class); + $this->logger = $this->createMock(LoggerInterface::class); $this->twofactorManager = $this->createMock(Manager::class); - $this->initialStateService = $this->createMock(IInitialStateService::class); + $this->initialState = $this->createMock(IInitialState::class); $this->verificationToken = $this->createMock(IVerificationToken::class); + $this->eventDispatcher = $this->createMock(IEventDispatcher::class); $this->lostController = new LostController( 'Core', $this->request, @@ -142,8 +142,9 @@ class LostControllerTest extends \Test\TestCase { $this->mailer, $this->logger, $this->twofactorManager, - $this->initialStateService, - $this->verificationToken + $this->initialState, + $this->verificationToken, + $this->eventDispatcher ); } @@ -175,6 +176,18 @@ class LostControllerTest extends \Test\TestCase { $this->verificationToken->expects($this->once()) ->method('check') ->with('MySecretToken', $this->existingUser, 'lostpassword', 'test@example.com'); + $this->urlGenerator + ->expects($this->once()) + ->method('linkToRouteAbsolute') + ->with('core.lost.setPassword', ['userId' => 'ValidTokenUser', 'token' => 'MySecretToken']) + ->willReturn('https://example.tld/index.php/lostpassword/set/sometoken/someuser'); + $this->initialState + ->expects($this->exactly(2)) + ->method('provideInitialState') + ->withConsecutive( + ['resetPasswordUser', 'ValidTokenUser'], + ['resetPasswordTarget', 'https://example.tld/index.php/lostpassword/set/sometoken/someuser'] + ); $response = $this->lostController->resetform('MySecretToken', 'ValidTokenUser'); $expectedResponse = new TemplateResponse('core', @@ -196,7 +209,7 @@ class LostControllerTest extends \Test\TestCase { ]); $this->logger->expects($this->exactly(0)) - ->method('logException'); + ->method('error'); $this->logger->expects($this->exactly(2)) ->method('warning'); @@ -243,11 +256,11 @@ class LostControllerTest extends \Test\TestCase { $message = $this->getMockBuilder('\OC\Mail\Message') ->disableOriginalConstructor()->getMock(); $message - ->expects($this->at(0)) + ->expects($this->once()) ->method('setTo') ->with(['test@example.com' => 'Existing User']); $message - ->expects($this->at(1)) + ->expects($this->once()) ->method('setFrom') ->with(['lostpassword-noreply@localhost' => null]); @@ -260,20 +273,20 @@ class LostControllerTest extends \Test\TestCase { ->willReturn('text body'); $message - ->expects($this->at(2)) + ->expects($this->once()) ->method('useTemplate') ->with($emailTemplate); $this->mailer - ->expects($this->at(0)) + ->expects($this->once()) ->method('createEMailTemplate') ->willReturn($emailTemplate); $this->mailer - ->expects($this->at(1)) + ->expects($this->once()) ->method('createMessage') ->willReturn($message); $this->mailer - ->expects($this->at(2)) + ->expects($this->once()) ->method('send') ->with($message); @@ -305,11 +318,11 @@ class LostControllerTest extends \Test\TestCase { $message = $this->getMockBuilder('\OC\Mail\Message') ->disableOriginalConstructor()->getMock(); $message - ->expects($this->at(0)) + ->expects($this->once()) ->method('setTo') ->with(['test@example.com' => 'Existing User']); $message - ->expects($this->at(1)) + ->expects($this->once()) ->method('setFrom') ->with(['lostpassword-noreply@localhost' => null]); @@ -322,20 +335,20 @@ class LostControllerTest extends \Test\TestCase { ->willReturn('text body'); $message - ->expects($this->at(2)) + ->expects($this->once()) ->method('useTemplate') ->with($emailTemplate); $this->mailer - ->expects($this->at(0)) + ->expects($this->once()) ->method('createEMailTemplate') ->willReturn($emailTemplate); $this->mailer - ->expects($this->at(1)) + ->expects($this->once()) ->method('createMessage') ->willReturn($message); $this->mailer - ->expects($this->at(2)) + ->expects($this->once()) ->method('send') ->with($message); @@ -361,11 +374,11 @@ class LostControllerTest extends \Test\TestCase { ->willReturn('https://example.tld/index.php/lostpassword/'); $message = $this->createMock(Message::class); $message - ->expects($this->at(0)) + ->expects($this->once()) ->method('setTo') ->with(['test@example.com' => 'Existing User']); $message - ->expects($this->at(1)) + ->expects($this->once()) ->method('setFrom') ->with(['lostpassword-noreply@localhost' => null]); @@ -378,26 +391,26 @@ class LostControllerTest extends \Test\TestCase { ->willReturn('text body'); $message - ->expects($this->at(2)) + ->expects($this->once()) ->method('useTemplate') ->with($emailTemplate); $this->mailer - ->expects($this->at(0)) + ->expects($this->once()) ->method('createEMailTemplate') ->willReturn($emailTemplate); $this->mailer - ->expects($this->at(1)) + ->expects($this->once()) ->method('createMessage') ->willReturn($message); $this->mailer - ->expects($this->at(2)) + ->expects($this->once()) ->method('send') ->with($message) ->will($this->throwException(new \Exception())); $this->logger->expects($this->exactly(1)) - ->method('logException'); + ->method('error'); $response = $this->lostController->email('ExistingUser'); $expectedResponse = new JSONResponse(['status' => 'success']); @@ -418,6 +431,11 @@ class LostControllerTest extends \Test\TestCase { $this->userManager->method('get') ->with('ValidTokenUser') ->willReturn($this->existingUser); + $beforePasswordResetEvent = new BeforePasswordResetEvent($this->existingUser, 'NewPassword'); + $this->eventDispatcher + ->expects($this->once()) + ->method('dispatchTyped') + ->with($beforePasswordResetEvent); $this->config->expects($this->never()) ->method('deleteUserValue'); @@ -439,6 +457,12 @@ class LostControllerTest extends \Test\TestCase { $this->userManager->method('get') ->with('ValidTokenUser') ->willReturn($this->existingUser); + $beforePasswordResetEvent = new BeforePasswordResetEvent($this->existingUser, 'NewPassword'); + $passwordResetEvent = new PasswordResetEvent($this->existingUser, 'NewPassword'); + $this->eventDispatcher + ->expects($this->exactly(2)) + ->method('dispatchTyped') + ->withConsecutive([$beforePasswordResetEvent], [$passwordResetEvent]); $this->config->expects($this->once()) ->method('deleteUserValue') ->with('ValidTokenUser', 'core', 'lostpassword'); @@ -549,7 +573,7 @@ class LostControllerTest extends \Test\TestCase { ->willReturn($user); $this->logger->expects($this->exactly(0)) - ->method('logException'); + ->method('error'); $this->logger->expects($this->once()) ->method('warning'); @@ -560,7 +584,7 @@ class LostControllerTest extends \Test\TestCase { } public function testSetPasswordEncryptionDontProceedPerUserKey() { - /** @var IEncryptionModule|\PHPUnit\Framework\MockObject\MockObject $encryptionModule */ + /** @var IEncryptionModule|MockObject $encryptionModule */ $encryptionModule = $this->createMock(IEncryptionModule::class); $encryptionModule->expects($this->once())->method('needDetailedAccessList')->willReturn(true); $this->encryptionManager->expects($this->once())->method('getEncryptionModules') @@ -632,7 +656,7 @@ class LostControllerTest extends \Test\TestCase { ->willReturn([$user1, $user2]); $this->logger->expects($this->exactly(0)) - ->method('logException'); + ->method('error'); $this->logger->expects($this->once()) ->method('warning'); diff --git a/tests/Core/Controller/TwoFactorChallengeControllerTest.php b/tests/Core/Controller/TwoFactorChallengeControllerTest.php index 561f243eb4b..94bb959fbbc 100644 --- a/tests/Core/Controller/TwoFactorChallengeControllerTest.php +++ b/tests/Core/Controller/TwoFactorChallengeControllerTest.php @@ -31,13 +31,13 @@ use OCP\Authentication\TwoFactorAuth\IActivatableAtLogin; use OCP\Authentication\TwoFactorAuth\ILoginSetupProvider; use OCP\Authentication\TwoFactorAuth\IProvider; use OCP\Authentication\TwoFactorAuth\TwoFactorException; -use OCP\ILogger; use OCP\IRequest; use OCP\ISession; use OCP\IURLGenerator; use OCP\IUser; use OCP\IUserSession; use OCP\Template; +use Psr\Log\LoggerInterface; use Test\TestCase; class TwoFactorChallengeControllerTest extends TestCase { @@ -57,7 +57,7 @@ class TwoFactorChallengeControllerTest extends TestCase { /** @var IURLGenerator|\PHPUnit\Framework\MockObject\MockObject */ private $urlGenerator; - /** @var ILogger|\PHPUnit\Framework\MockObject\MockObject */ + /** @var LoggerInterface|\PHPUnit\Framework\MockObject\MockObject */ private $logger; /** @var TwoFactorChallengeController|\PHPUnit\Framework\MockObject\MockObject */ @@ -71,7 +71,7 @@ class TwoFactorChallengeControllerTest extends TestCase { $this->userSession = $this->createMock(IUserSession::class); $this->session = $this->createMock(ISession::class); $this->urlGenerator = $this->createMock(IURLGenerator::class); - $this->logger = $this->createMock(ILogger::class); + $this->logger = $this->createMock(LoggerInterface::class); $this->controller = $this->getMockBuilder(TwoFactorChallengeController::class) ->setConstructorArgs([ diff --git a/tests/Core/Service/LoginFlowV2ServiceUnitTest.php b/tests/Core/Service/LoginFlowV2ServiceUnitTest.php index 18b2f370fb3..c3128dca334 100644 --- a/tests/Core/Service/LoginFlowV2ServiceUnitTest.php +++ b/tests/Core/Service/LoginFlowV2ServiceUnitTest.php @@ -34,9 +34,10 @@ use OC\Core\Service\LoginFlowV2Service; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Utility\ITimeFactory; use OCP\IConfig; -use OCP\ILogger; use OCP\Security\ICrypto; use OCP\Security\ISecureRandom; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\LoggerInterface; use Test\TestCase; /** @@ -49,7 +50,7 @@ class LoginFlowV2ServiceUnitTest extends TestCase { /** @var \OCP\Security\ICrypto */ private $crypto; - /** @var \OCP\ILogger */ + /** @var LoggerInterface|MockObject */ private $logger; /** @var \OC\Core\Db\LoginFlowV2Mapper */ @@ -88,7 +89,7 @@ class LoginFlowV2ServiceUnitTest extends TestCase { $this->mapper = $this->getMockBuilder(LoginFlowV2Mapper::class) ->disableOriginalConstructor()->getMock(); - $this->logger = $this->getMockBuilder(ILogger::class) + $this->logger = $this->getMockBuilder(LoggerInterface::class) ->disableOriginalConstructor()->getMock(); $this->tokenProvider = $this->getMockBuilder(IProvider::class) diff --git a/tests/Test/Repair/Owncloud/CleanPreviewsBackgroundJobTest.php b/tests/Test/Repair/Owncloud/CleanPreviewsBackgroundJobTest.php index 8ecef60c35d..3c15d51fd61 100644 --- a/tests/Test/Repair/Owncloud/CleanPreviewsBackgroundJobTest.php +++ b/tests/Test/Repair/Owncloud/CleanPreviewsBackgroundJobTest.php @@ -107,12 +107,12 @@ class CleanPreviewsBackgroundJobTest extends TestCase { $this->equalTo(['uid' => 'myuid']) ); - $this->logger->expects($this->at(0)) + $this->logger->expects($this->exactly(2)) ->method('info') - ->with($this->equalTo('Started preview cleanup for myuid')); - $this->logger->expects($this->at(1)) - ->method('info') - ->with($this->equalTo('New preview cleanup scheduled for myuid')); + ->withConsecutive( + [$this->equalTo('Started preview cleanup for myuid')], + [$this->equalTo('New preview cleanup scheduled for myuid')], + ); $this->job->run(['uid' => 'myuid']); } @@ -146,12 +146,12 @@ class CleanPreviewsBackgroundJobTest extends TestCase { $this->jobList->expects($this->never()) ->method('add'); - $this->logger->expects($this->at(0)) - ->method('info') - ->with($this->equalTo('Started preview cleanup for myuid')); - $this->logger->expects($this->at(1)) + $this->logger->expects($this->exactly(2)) ->method('info') - ->with($this->equalTo('Preview cleanup done for myuid')); + ->withConsecutive( + [$this->equalTo('Started preview cleanup for myuid')], + [$this->equalTo('Preview cleanup done for myuid')], + ); $thumbnailFolder->expects($this->once()) ->method('delete'); @@ -165,12 +165,12 @@ class CleanPreviewsBackgroundJobTest extends TestCase { ->with($this->equalTo('myuid')) ->willThrowException(new NotFoundException()); - $this->logger->expects($this->at(0)) - ->method('info') - ->with($this->equalTo('Started preview cleanup for myuid')); - $this->logger->expects($this->at(1)) + $this->logger->expects($this->exactly(2)) ->method('info') - ->with($this->equalTo('Preview cleanup done for myuid')); + ->withConsecutive( + [$this->equalTo('Started preview cleanup for myuid')], + [$this->equalTo('Preview cleanup done for myuid')], + ); $this->job->run(['uid' => 'myuid']); } @@ -189,12 +189,12 @@ class CleanPreviewsBackgroundJobTest extends TestCase { ->with($this->equalTo('thumbnails')) ->willThrowException(new NotFoundException()); - $this->logger->expects($this->at(0)) - ->method('info') - ->with($this->equalTo('Started preview cleanup for myuid')); - $this->logger->expects($this->at(1)) + $this->logger->expects($this->exactly(2)) ->method('info') - ->with($this->equalTo('Preview cleanup done for myuid')); + ->withConsecutive( + [$this->equalTo('Started preview cleanup for myuid')], + [$this->equalTo('Preview cleanup done for myuid')], + ); $this->job->run(['uid' => 'myuid']); } @@ -229,12 +229,12 @@ class CleanPreviewsBackgroundJobTest extends TestCase { $this->jobList->expects($this->never()) ->method('add'); - $this->logger->expects($this->at(0)) + $this->logger->expects($this->exactly(2)) ->method('info') - ->with($this->equalTo('Started preview cleanup for myuid')); - $this->logger->expects($this->at(1)) - ->method('info') - ->with($this->equalTo('Preview cleanup done for myuid')); + ->withConsecutive( + [$this->equalTo('Started preview cleanup for myuid')], + [$this->equalTo('Preview cleanup done for myuid')], + ); $thumbnailFolder->expects($this->once()) ->method('delete') diff --git a/tests/Test/Repair/Owncloud/CleanPreviewsTest.php b/tests/Test/Repair/Owncloud/CleanPreviewsTest.php index abd166057be..7a6c374a2d7 100644 --- a/tests/Test/Repair/Owncloud/CleanPreviewsTest.php +++ b/tests/Test/Repair/Owncloud/CleanPreviewsTest.php @@ -79,18 +79,17 @@ class CleanPreviewsTest extends TestCase { $function($user2); })); - $this->jobList->expects($this->at(0)) + $this->jobList->expects($this->exactly(2)) ->method('add') - ->with( - $this->equalTo(CleanPreviewsBackgroundJob::class), - $this->equalTo(['uid' => 'user1']) - ); - - $this->jobList->expects($this->at(1)) - ->method('add') - ->with( - $this->equalTo(CleanPreviewsBackgroundJob::class), - $this->equalTo(['uid' => 'user2']) + ->withConsecutive( + [ + $this->equalTo(CleanPreviewsBackgroundJob::class), + $this->equalTo(['uid' => 'user1']) + ], + [ + $this->equalTo(CleanPreviewsBackgroundJob::class), + $this->equalTo(['uid' => 'user2']) + ], ); $this->config->expects($this->once()) diff --git a/tests/Test/Repair/Owncloud/UpdateLanguageCodesTest.php b/tests/Test/Repair/Owncloud/UpdateLanguageCodesTest.php index 3b0b2f57f5f..b5d339eef2f 100644 --- a/tests/Test/Repair/Owncloud/UpdateLanguageCodesTest.php +++ b/tests/Test/Repair/Owncloud/UpdateLanguageCodesTest.php @@ -96,27 +96,17 @@ class UpdateLanguageCodesTest extends TestCase { /** @var IOutput|\PHPUnit_Framework_MockObject_MockObject $outputMock */ $outputMock = $this->createMock(IOutput::class); - $outputMock->expects($this->at(0)) + $outputMock->expects($this->exactly(7)) ->method('info') - ->with('Changed 1 setting(s) from "bg_BG" to "bg" in preferences table.'); - $outputMock->expects($this->at(1)) - ->method('info') - ->with('Changed 0 setting(s) from "cs_CZ" to "cs" in preferences table.'); - $outputMock->expects($this->at(2)) - ->method('info') - ->with('Changed 1 setting(s) from "fi_FI" to "fi" in preferences table.'); - $outputMock->expects($this->at(3)) - ->method('info') - ->with('Changed 0 setting(s) from "hu_HU" to "hu" in preferences table.'); - $outputMock->expects($this->at(4)) - ->method('info') - ->with('Changed 0 setting(s) from "nb_NO" to "nb" in preferences table.'); - $outputMock->expects($this->at(5)) - ->method('info') - ->with('Changed 0 setting(s) from "sk_SK" to "sk" in preferences table.'); - $outputMock->expects($this->at(6)) - ->method('info') - ->with('Changed 2 setting(s) from "th_TH" to "th" in preferences table.'); + ->withConsecutive( + ['Changed 1 setting(s) from "bg_BG" to "bg" in preferences table.'], + ['Changed 0 setting(s) from "cs_CZ" to "cs" in preferences table.'], + ['Changed 1 setting(s) from "fi_FI" to "fi" in preferences table.'], + ['Changed 0 setting(s) from "hu_HU" to "hu" in preferences table.'], + ['Changed 0 setting(s) from "nb_NO" to "nb" in preferences table.'], + ['Changed 0 setting(s) from "sk_SK" to "sk" in preferences table.'], + ['Changed 2 setting(s) from "th_TH" to "th" in preferences table.'], + ); $this->config->expects($this->once()) ->method('getSystemValue') diff --git a/tests/acceptance/composer.json b/tests/acceptance/composer.json index a2ec896d94e..25f74d463d8 100644 --- a/tests/acceptance/composer.json +++ b/tests/acceptance/composer.json @@ -4,7 +4,7 @@ "behat/mink": "1.8.1", "behat/mink-extension": "2.3.1", "behat/mink-selenium2-driver": "1.4.0", - "phpunit/phpunit": "6.5.14" + "phpunit/phpunit": "9.5.19" }, "autoload": { "psr-4": { diff --git a/tests/acceptance/composer.lock b/tests/acceptance/composer.lock index 20d93036ba9..cd21217a9b1 100644 --- a/tests/acceptance/composer.lock +++ b/tests/acceptance/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d2c44a0ea2452a05e7f45d8ca6ef0387", + "content-hash": "0b9561c5aa752c7c6746fc2d13e2e7cb", "packages": [], "packages-dev": [ { @@ -85,29 +85,33 @@ "symfony", "testing" ], + "support": { + "issues": "https://github.com/Behat/Behat/issues", + "source": "https://github.com/Behat/Behat/tree/v3.8.1" + }, "time": "2020-11-07T15:55:18+00:00" }, { "name": "behat/gherkin", - "version": "v4.6.2", + "version": "v4.9.0", "source": { "type": "git", "url": "https://github.com/Behat/Gherkin.git", - "reference": "51ac4500c4dc30cbaaabcd2f25694299df666a31" + "reference": "0bc8d1e30e96183e4f36db9dc79caead300beff4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/Gherkin/zipball/51ac4500c4dc30cbaaabcd2f25694299df666a31", - "reference": "51ac4500c4dc30cbaaabcd2f25694299df666a31", + "url": "https://api.github.com/repos/Behat/Gherkin/zipball/0bc8d1e30e96183e4f36db9dc79caead300beff4", + "reference": "0bc8d1e30e96183e4f36db9dc79caead300beff4", "shasum": "" }, "require": { - "php": ">=5.3.1" + "php": "~7.2|~8.0" }, "require-dev": { - "phpunit/phpunit": "~4.5|~5", - "symfony/phpunit-bridge": "~2.7|~3|~4", - "symfony/yaml": "~2.3|~3|~4" + "cucumber/cucumber": "dev-gherkin-22.0.0", + "phpunit/phpunit": "~8|~9", + "symfony/yaml": "~3|~4|~5" }, "suggest": { "symfony/yaml": "If you want to parse features, represented in YAML files" @@ -115,7 +119,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4-dev" + "dev-master": "4.x-dev" } }, "autoload": { @@ -134,7 +138,7 @@ "homepage": "http://everzet.com" } ], - "description": "Gherkin DSL parser for PHP 5.3", + "description": "Gherkin DSL parser for PHP", "homepage": "http://behat.org/", "keywords": [ "BDD", @@ -144,7 +148,11 @@ "gherkin", "parser" ], - "time": "2020-03-17T14:03:26+00:00" + "support": { + "issues": "https://github.com/Behat/Gherkin/issues", + "source": "https://github.com/Behat/Gherkin/tree/v4.9.0" + }, + "time": "2021-10-12T13:05:09+00:00" }, { "name": "behat/mink", @@ -205,6 +213,10 @@ "testing", "web" ], + "support": { + "issues": "https://github.com/minkphp/Mink/issues", + "source": "https://github.com/minkphp/Mink/tree/v1.8.1" + }, "time": "2020-03-11T15:45:53+00:00" }, { @@ -264,6 +276,10 @@ "test", "web" ], + "support": { + "issues": "https://github.com/Behat/MinkExtension/issues", + "source": "https://github.com/Behat/MinkExtension/tree/master" + }, "time": "2018-02-06T15:36:30+00:00" }, { @@ -325,34 +341,38 @@ "testing", "webdriver" ], + "support": { + "issues": "https://github.com/minkphp/MinkSelenium2Driver/issues", + "source": "https://github.com/minkphp/MinkSelenium2Driver/tree/v1.4.0" + }, "time": "2020-03-11T14:43:21+00:00" }, { "name": "behat/transliterator", - "version": "v1.3.0", + "version": "v1.5.0", "source": { "type": "git", "url": "https://github.com/Behat/Transliterator.git", - "reference": "3c4ec1d77c3d05caa1f0bf8fb3aae4845005c7fc" + "reference": "baac5873bac3749887d28ab68e2f74db3a4408af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/Transliterator/zipball/3c4ec1d77c3d05caa1f0bf8fb3aae4845005c7fc", - "reference": "3c4ec1d77c3d05caa1f0bf8fb3aae4845005c7fc", + "url": "https://api.github.com/repos/Behat/Transliterator/zipball/baac5873bac3749887d28ab68e2f74db3a4408af", + "reference": "baac5873bac3749887d28ab68e2f74db3a4408af", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.2" }, "require-dev": { "chuyskywalker/rolling-curl": "^3.1", "php-yaoi/php-yaoi": "^1.0", - "phpunit/phpunit": "^4.8.36|^6.3" + "phpunit/phpunit": "^8.5.25 || ^9.5.19" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.x-dev" } }, "autoload": { @@ -370,33 +390,38 @@ "slug", "transliterator" ], - "time": "2020-01-14T16:39:13+00:00" + "support": { + "issues": "https://github.com/Behat/Transliterator/issues", + "source": "https://github.com/Behat/Transliterator/tree/v1.5.0" + }, + "time": "2022-03-30T09:27:43+00:00" }, { "name": "doctrine/instantiator", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^8.0", + "doctrine/coding-standard": "^9", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.22" }, "type": "library", "autoload": { @@ -421,20 +446,38 @@ "constructor", "instantiate" ], - "time": "2020-11-10T18:47:58+00:00" + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-03-03T08:28:38+00:00" }, { "name": "instaclick/php-webdriver", - "version": "1.4.7", + "version": "1.4.14", "source": { "type": "git", "url": "https://github.com/instaclick/php-webdriver.git", - "reference": "b5f330e900e9b3edfc18024a5ec8c07136075712" + "reference": "200b8df772b74d604bebf25ef42ad6f8ee6380a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/b5f330e900e9b3edfc18024a5ec8c07136075712", - "reference": "b5f330e900e9b3edfc18024a5ec8c07136075712", + "url": "https://api.github.com/repos/instaclick/php-webdriver/zipball/200b8df772b74d604bebf25ef42ad6f8ee6380a9", + "reference": "200b8df772b74d604bebf25ef42ad6f8ee6380a9", "shasum": "" }, "require": { @@ -442,8 +485,8 @@ "php": ">=5.3.2" }, "require-dev": { - "phpunit/phpunit": "^4.8", - "satooshi/php-coveralls": "^1.0||^2.0" + "phpunit/phpunit": "^8.5 || ^9.5", + "satooshi/php-coveralls": "^1.0 || ^2.0" }, "type": "library", "extra": { @@ -480,41 +523,46 @@ "webdriver", "webtest" ], - "time": "2019-09-25T09:05:11+00:00" + "support": { + "issues": "https://github.com/instaclick/php-webdriver/issues", + "source": "https://github.com/instaclick/php-webdriver/tree/1.4.14" + }, + "time": "2022-04-19T02:06:59+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.10.2", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, - "replace": { - "myclabs/deep-copy": "self.version" + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" }, "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, "files": [ "src/DeepCopy/deep_copy.php" - ] + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -528,32 +576,99 @@ "object", "object graph" ], - "time": "2020-11-13T09:40:50+00:00" + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2022-03-03T13:19:32+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.14.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" + }, + "time": "2022-05-31T20:59:12+00:00" }, { "name": "phar-io/manifest", - "version": "1.0.1", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", "shasum": "" }, "require": { "ext-dom": "*", "ext-phar": "*", - "phar-io/version": "^1.0.1", - "php": "^5.6 || ^7.0" + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -583,24 +698,28 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2017-03-05T18:14:27+00:00" + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" }, { "name": "phar-io/version", - "version": "1.0.1", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { @@ -630,7 +749,11 @@ } ], "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -679,20 +802,24 @@ "reflection", "static analysis" ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, "time": "2020-06-27T09:03:43+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.2.2", + "version": "5.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", "shasum": "" }, "require": { @@ -703,7 +830,8 @@ "webmozart/assert": "^1.9.1" }, "require-dev": { - "mockery/mockery": "~1.3.2" + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" }, "type": "library", "extra": { @@ -731,20 +859,24 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2020-09-03T19:13:55+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.4.0", + "version": "1.6.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" + "reference": "77a32518733312af16a44300404e945338981de3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", + "reference": "77a32518733312af16a44300404e945338981de3", "shasum": "" }, "require": { @@ -752,7 +884,8 @@ "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "ext-tokenizer": "*" + "ext-tokenizer": "*", + "psalm/phar": "^4.8" }, "type": "library", "extra": { @@ -776,37 +909,41 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2020-09-17T18:55:26+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" + }, + "time": "2022-03-15T21:29:03+00:00" }, { "name": "phpspec/prophecy", - "version": "v1.10.3", + "version": "v1.15.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "451c3cd1418cf640de218914901e51b064abb093" + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", - "reference": "451c3cd1418cf640de218914901e51b064abb093", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" + "doctrine/instantiator": "^1.2", + "php": "^7.2 || ~8.0, <8.2", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { - "phpspec/phpspec": "^2.5 || ^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + "phpspec/phpspec": "^6.0 || ^7.0", + "phpunit/phpunit": "^8.0 || ^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.10.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { @@ -839,44 +976,52 @@ "spy", "stub" ], - "time": "2020-03-05T15:02:03+00:00" + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" + }, + "time": "2021-12-08T12:19:24+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "5.3.2", + "version": "9.2.15", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "c89677919c5dd6d3b3852f230a663118762218ac" + "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac", - "reference": "c89677919c5dd6d3b3852f230a663118762218ac", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f", + "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-xmlwriter": "*", - "php": "^7.0", - "phpunit/php-file-iterator": "^1.4.2", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^2.0.1", - "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.0", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" + "nikic/php-parser": "^4.13.0", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^9.3" }, "suggest": { - "ext-xdebug": "^2.5.5" + "ext-pcov": "*", + "ext-xdebug": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.3.x-dev" + "dev-master": "9.2-dev" } }, "autoload": { @@ -902,29 +1047,42 @@ "testing", "xunit" ], - "time": "2018-04-06T15:36:58+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-03-07T09:28:20+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.5", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4.x-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -939,7 +1097,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -949,26 +1107,48 @@ "filesystem", "iterator" ], - "time": "2017-11-27T13:52:08+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" }, { - "name": "phpunit/php-text-template", - "version": "1.2.1", + "name": "phpunit/php-invoker", + "version": "3.1.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -985,37 +1165,47 @@ "role": "lead" } ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", "keywords": [ - "template" + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } ], - "time": "2015-06-21T13:50:34+00:00" + "time": "2020-09-28T05:58:55+00:00" }, { - "name": "phpunit/php-timer", - "version": "1.0.9", + "name": "phpunit/php-text-template", + "version": "2.0.4", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1030,42 +1220,51 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ - "timer" + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } ], - "time": "2017-02-26T11:10:40+00:00" + "time": "2020-10-26T05:33:50+00:00" }, { - "name": "phpunit/php-token-stream", - "version": "2.0.2", + "name": "phpunit/php-timer", + "version": "5.0.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "791198a2c6254db10131eecfe8c06670700904db" + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", - "reference": "791198a2c6254db10131eecfe8c06670700904db", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": "^7.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^6.2.4" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -1080,66 +1279,78 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", "keywords": [ - "tokenizer" + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } ], - "abandoned": true, - "time": "2017-11-27T05:48:46+00:00" + "time": "2020-10-26T13:16:10+00:00" }, { "name": "phpunit/phpunit", - "version": "6.5.14", + "version": "9.5.19", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7" + "reference": "35ea4b7f3acabb26f4bb640f8c30866c401da807" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bac23fe7ff13dbdb461481f706f0e9fe746334b7", - "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/35ea4b7f3acabb26f4bb640f8c30866c401da807", + "reference": "35ea4b7f3acabb26f4bb640f8c30866c401da807", "shasum": "" }, "require": { + "doctrine/instantiator": "^1.3.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "myclabs/deep-copy": "^1.6.1", - "phar-io/manifest": "^1.0.1", - "phar-io/version": "^1.0", - "php": "^7.0", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^5.3", - "phpunit/php-file-iterator": "^1.4.3", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^1.0.9", - "phpunit/phpunit-mock-objects": "^5.0.9", - "sebastian/comparator": "^2.1", - "sebastian/diff": "^2.0", - "sebastian/environment": "^3.1", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^1.0", - "sebastian/version": "^2.0.1" - }, - "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2", - "phpunit/dbunit": "<3.0" + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpspec/prophecy": "^1.12.1", + "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.5", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.3", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^3.0", + "sebastian/version": "^3.0.2" }, "require-dev": { - "ext-pdo": "*" + "ext-pdo": "*", + "phpspec/prophecy-phpunit": "^2.0.1" }, "suggest": { - "ext-xdebug": "*", - "phpunit/php-invoker": "^1.1" + "ext-soap": "*", + "ext-xdebug": "*" }, "bin": [ "phpunit" @@ -1147,10 +1358,13 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "6.5.x-dev" + "dev-master": "9.5-dev" } }, "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], "classmap": [ "src/" ] @@ -1173,91 +1387,40 @@ "testing", "xunit" ], - "time": "2019-02-01T05:22:47+00:00" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "5.0.10", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/cd1cf05c553ecfec36b170070573e540b67d3f1f", - "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.5", - "php": "^7.0", - "phpunit/php-text-template": "^1.2.1", - "sebastian/exporter": "^3.1" - }, - "conflict": { - "phpunit/phpunit": "<6.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.5.11" - }, - "suggest": { - "ext-soap": "*" + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.19" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ + "funding": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" } ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "abandoned": true, - "time": "2018-08-09T05:50:03+00:00" + "time": "2022-03-15T09:57:31+00:00" }, { "name": "psr/container", - "version": "1.0.0", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.4.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -1270,7 +1433,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", @@ -1282,7 +1445,11 @@ "container-interop", "psr" ], - "time": "2017-02-14T16:28:37+00:00" + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.2" + }, + "time": "2021-11-05T16:50:12+00:00" }, { "name": "psr/event-dispatcher", @@ -1328,32 +1495,148 @@ "psr", "psr-14" ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, "time": "2019-01-08T18:20:26+00:00" }, { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", "shasum": "" }, "require": { - "php": ">=5.6" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^8.5" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1373,34 +1656,44 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2020-11-30T08:15:22+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" }, { "name": "sebastian/comparator", - "version": "2.1.3", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" + "reference": "55f4261989e546dc112258c7a75935a81a7ce382" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382", "shasum": "" }, "require": { - "php": "^7.0", - "sebastian/diff": "^2.0 || ^3.0", - "sebastian/exporter": "^3.1" + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^6.4" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1.x-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1414,6 +1707,10 @@ ], "authors": [ { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" }, @@ -1424,10 +1721,6 @@ { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" } ], "description": "Provides the functionality to compare PHP values for equality", @@ -1437,27 +1730,38 @@ "compare", "equality" ], - "time": "2018-02-01T13:46:46+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:49:45+00:00" }, { - "name": "sebastian/diff", - "version": "2.0.1", + "name": "sebastian/complexity", + "version": "2.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", "shasum": "" }, "require": { - "php": "^7.0" + "nikic/php-parser": "^4.7", + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^6.2" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { @@ -1476,45 +1780,118 @@ ], "authors": [ { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" } ], "description": "Diff implementation", "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ - "diff" + "diff", + "udiff", + "unidiff", + "unified diff" ], - "time": "2017-08-03T08:09:46+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" }, { "name": "sebastian/environment", - "version": "3.1.0", + "version": "5.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", - "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^6.1" + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1.x-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -1539,34 +1916,44 @@ "environment", "hhvm" ], - "time": "2017-07-01T08:51:00+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-04-03T09:37:03+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.3", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e" + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e", - "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", "shasum": "" }, "require": { - "php": ">=7.0", - "sebastian/recursion-context": "^3.0" + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" }, "require-dev": { "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1.x-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1601,32 +1988,45 @@ } ], "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", + "homepage": "https://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], - "time": "2020-11-30T07:47:53+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-11-11T14:18:36+00:00" }, { "name": "sebastian/global-state", - "version": "2.0.0", + "version": "5.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "ext-dom": "*", + "phpunit/phpunit": "^9.3" }, "suggest": { "ext-uopz": "*" @@ -1634,7 +2034,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -1657,34 +2057,101 @@ "keywords": [ "global state" ], - "time": "2017-04-27T15:39:26+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-02-14T08:28:10+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" }, { "name": "sebastian/object-enumerator", - "version": "3.0.4", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", "shasum": "" }, "require": { - "php": ">=7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1704,32 +2171,42 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2020-11-30T07:40:27+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" }, { "name": "sebastian/object-reflector", - "version": "1.1.2", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", "shasum": "" }, "require": { - "php": ">=7.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1749,32 +2226,42 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "time": "2020-11-30T07:37:18+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" }, { "name": "sebastian/recursion-context", - "version": "3.0.1", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", "shasum": "" }, "require": { - "php": ">=7.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1802,29 +2289,42 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2020-11-30T07:34:24+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:17:30+00:00" }, { "name": "sebastian/resource-operations", - "version": "1.0.0", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", "shasum": "" }, "require": { - "php": ">=5.6.0" + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1844,29 +2344,95 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-03-15T09:54:48+00:00" }, { "name": "sebastian/version", - "version": "2.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + "reference": "c6c1022351a901512170118436c764e473f6de8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", "shasum": "" }, "require": { - "php": ">=5.6" + "php": ">=7.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1887,26 +2453,38 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2016-10-03T07:35:21+00:00" + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" }, { "name": "symfony/config", - "version": "v4.4.18", + "version": "v4.4.42", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "e501c56d2fa70798075b9811d0eb4c27de491459" + "reference": "83cdafd1bd3370de23e3dc2ed01026908863be81" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/e501c56d2fa70798075b9811d0eb4c27de491459", - "reference": "e501c56d2fa70798075b9811d0eb4c27de491459", + "url": "https://api.github.com/repos/symfony/config/zipball/83cdafd1bd3370de23e3dc2ed01026908863be81", + "reference": "83cdafd1bd3370de23e3dc2ed01026908863be81", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/filesystem": "^3.4|^4.0|^5.0", - "symfony/polyfill-ctype": "~1.8" + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php80": "^1.16", + "symfony/polyfill-php81": "^1.22" }, "conflict": { "symfony/finder": "<3.4" @@ -1944,33 +2522,52 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Config Component", + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", - "time": "2020-12-09T08:58:17+00:00" + "support": { + "source": "https://github.com/symfony/config/tree/v4.4.42" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-17T07:10:14+00:00" }, { "name": "symfony/console", - "version": "v5.2.1", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "47c02526c532fb381374dab26df05e7313978976" + "reference": "829d5d1bf60b2efeb0887b7436873becc71a45eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/47c02526c532fb381374dab26df05e7313978976", - "reference": "47c02526c532fb381374dab26df05e7313978976", + "url": "https://api.github.com/repos/symfony/console/zipball/829d5d1bf60b2efeb0887b7436873becc71a45eb", + "reference": "829d5d1bf60b2efeb0887b7436873becc71a45eb", "shasum": "" }, "require": { "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.8", - "symfony/polyfill-php80": "^1.15", - "symfony/service-contracts": "^1.1|^2", - "symfony/string": "^5.1" + "symfony/polyfill-php73": "^1.9", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.1|^6.0" }, "conflict": { + "psr/log": ">=3", "symfony/dependency-injection": "<4.4", "symfony/dotenv": "<5.1", "symfony/event-dispatcher": "<4.4", @@ -1978,16 +2575,16 @@ "symfony/process": "<4.4" }, "provide": { - "psr/log-implementation": "1.0" + "psr/log-implementation": "1.0|2.0" }, "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/event-dispatcher": "^4.4|^5.0", - "symfony/lock": "^4.4|^5.0", - "symfony/process": "^4.4|^5.0", - "symfony/var-dumper": "^4.4|^5.0" + "psr/log": "^1|^2", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/event-dispatcher": "^4.4|^5.0|^6.0", + "symfony/lock": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/var-dumper": "^4.4|^5.0|^6.0" }, "suggest": { "psr/log": "For using the console logger", @@ -2018,7 +2615,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Console Component", + "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", "keywords": [ "cli", @@ -2026,24 +2623,42 @@ "console", "terminal" ], - "time": "2020-12-18T08:03:05+00:00" + "support": { + "source": "https://github.com/symfony/console/tree/v5.4.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-18T06:17:34+00:00" }, { "name": "symfony/css-selector", - "version": "v5.2.1", + "version": "v5.4.3", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "f789e7ead4c79e04ca9a6d6162fc629c89bd8054" + "reference": "b0a190285cd95cb019237851205b8140ef6e368e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/f789e7ead4c79e04ca9a6d6162fc629c89bd8054", - "reference": "f789e7ead4c79e04ca9a6d6162fc629c89bd8054", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/b0a190285cd95cb019237851205b8140ef6e368e", + "reference": "b0a190285cd95cb019237851205b8140ef6e368e", "shasum": "" }, "require": { - "php": ">=7.2.5" + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -2072,43 +2687,61 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony CssSelector Component", + "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", - "time": "2020-12-08T17:02:38+00:00" + "support": { + "source": "https://github.com/symfony/css-selector/tree/v5.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:53:40+00:00" }, { "name": "symfony/dependency-injection", - "version": "v4.4.18", + "version": "v4.4.42", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "3860f64c6deb2cb48b1ada27460c58ae479bdc0f" + "reference": "f6fdbf252765a09c7ac243617f79f1babef792c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/3860f64c6deb2cb48b1ada27460c58ae479bdc0f", - "reference": "3860f64c6deb2cb48b1ada27460c58ae479bdc0f", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f6fdbf252765a09c7ac243617f79f1babef792c9", + "reference": "f6fdbf252765a09c7ac243617f79f1babef792c9", "shasum": "" }, "require": { "php": ">=7.1.3", "psr/container": "^1.0", + "symfony/polyfill-php80": "^1.16", "symfony/service-contracts": "^1.1.6|^2" }, "conflict": { "symfony/config": "<4.3|>=5.0", "symfony/finder": "<3.4", "symfony/proxy-manager-bridge": "<3.4", - "symfony/yaml": "<3.4" + "symfony/yaml": "<4.4.26" }, "provide": { "psr/container-implementation": "1.0", - "symfony/service-implementation": "1.0" + "symfony/service-implementation": "1.0|2.0" }, "require-dev": { "symfony/config": "^4.3", "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/yaml": "^3.4|^4.0|^5.0" + "symfony/yaml": "^4.4.26|^5.0" }, "suggest": { "symfony/config": "", @@ -2140,22 +2773,39 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony DependencyInjection Component", + "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", - "time": "2020-12-18T07:41:31+00:00" + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/v4.4.42" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T15:15:52+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.2.0", + "version": "v2.5.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665" + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665", - "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", "shasum": "" }, "require": { @@ -2164,7 +2814,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -2192,27 +2842,44 @@ ], "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", - "time": "2020-09-07T11:33:47+00:00" + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:53:40+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v5.2.1", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "1c93f7a1dff592c252574c79a8635a8a80856042" + "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1c93f7a1dff592c252574c79a8635a8a80856042", - "reference": "1c93f7a1dff592c252574c79a8635a8a80856042", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", + "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/event-dispatcher-contracts": "^2", - "symfony/polyfill-php80": "^1.15" + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/event-dispatcher-contracts": "^2|^3", + "symfony/polyfill-php80": "^1.16" }, "conflict": { "symfony/dependency-injection": "<4.4" @@ -2222,14 +2889,14 @@ "symfony/event-dispatcher-implementation": "2.0" }, "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/error-handler": "^4.4|^5.0", - "symfony/expression-language": "^4.4|^5.0", - "symfony/http-foundation": "^4.4|^5.0", - "symfony/service-contracts": "^1.1|^2", - "symfony/stopwatch": "^4.4|^5.0" + "psr/log": "^1|^2|^3", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/expression-language": "^4.4|^5.0|^6.0", + "symfony/http-foundation": "^4.4|^5.0|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/stopwatch": "^4.4|^5.0|^6.0" }, "suggest": { "symfony/dependency-injection": "", @@ -2258,22 +2925,39 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony EventDispatcher Component", + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", - "time": "2020-12-18T08:03:05+00:00" + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-05T16:45:39+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v2.2.0", + "version": "v2.5.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "0ba7d54483095a198fa51781bc608d17e84dffa2" + "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0ba7d54483095a198fa51781bc608d17e84dffa2", - "reference": "0ba7d54483095a198fa51781bc608d17e84dffa2", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/f98b54df6ad059855739db6fcbc2d36995283fe1", + "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1", "shasum": "" }, "require": { @@ -2286,7 +2970,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -2322,25 +3006,44 @@ "interoperability", "standards" ], - "time": "2020-09-07T11:33:47+00:00" + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:53:40+00:00" }, { "name": "symfony/filesystem", - "version": "v5.2.1", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "fa8f8cab6b65e2d99a118e082935344c5ba8c60d" + "reference": "36a017fa4cce1eff1b8e8129ff53513abcef05ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/fa8f8cab6b65e2d99a118e082935344c5ba8c60d", - "reference": "fa8f8cab6b65e2d99a118e082935344c5ba8c60d", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/36a017fa4cce1eff1b8e8129ff53513abcef05ba", + "reference": "36a017fa4cce1eff1b8e8129ff53513abcef05ba", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/polyfill-ctype": "~1.8" + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8", + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -2365,34 +3068,54 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Filesystem Component", + "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", - "time": "2020-11-30T17:05:38+00:00" + "support": { + "source": "https://github.com/symfony/filesystem/tree/v5.4.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-20T13:55:35+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.22.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", "shasum": "" }, "require": { "php": ">=7.1" }, + "provide": { + "ext-ctype": "*" + }, "suggest": { "ext-ctype": "For best performance" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2400,12 +3123,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2429,20 +3152,37 @@ "polyfill", "portable" ], - "time": "2021-01-07T16:49:33+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.22.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "267a9adeb8ecb8071040a740930e077cdfb987af" + "reference": "433d05519ce6990bf3530fba6957499d327395c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/267a9adeb8ecb8071040a740930e077cdfb987af", - "reference": "267a9adeb8ecb8071040a740930e077cdfb987af", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", + "reference": "433d05519ce6990bf3530fba6957499d327395c2", "shasum": "" }, "require": { @@ -2454,7 +3194,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2462,12 +3202,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2493,20 +3233,37 @@ "portable", "shim" ], - "time": "2021-01-07T16:49:33+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.22.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "6e971c891537eb617a00bb07a43d182a6915faba" + "reference": "219aa369ceff116e673852dce47c3a41794c14bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/6e971c891537eb617a00bb07a43d182a6915faba", - "reference": "6e971c891537eb617a00bb07a43d182a6915faba", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", + "reference": "219aa369ceff116e673852dce47c3a41794c14bd", "shasum": "" }, "require": { @@ -2518,7 +3275,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2526,12 +3283,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, "files": [ "bootstrap.php" ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, "classmap": [ "Resources/stubs" ] @@ -2560,32 +3317,52 @@ "portable", "shim" ], - "time": "2021-01-07T17:09:11+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.22.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13" + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", - "reference": "f377a3dd1fde44d37b9831d68dc8dea3ffd28e13", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", "shasum": "" }, "require": { "php": ">=7.1" }, + "provide": { + "ext-mbstring": "*" + }, "suggest": { "ext-mbstring": "For best performance" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2593,12 +3370,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2623,20 +3400,37 @@ "portable", "shim" ], - "time": "2021-01-07T16:49:33+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.22.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2" + "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", - "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85", + "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85", "shasum": "" }, "require": { @@ -2645,7 +3439,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2653,12 +3447,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, "files": [ "bootstrap.php" ], + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, "classmap": [ "Resources/stubs" ] @@ -2685,20 +3479,37 @@ "portable", "shim" ], - "time": "2021-01-07T16:49:33+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.22.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91" + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91", - "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", "shasum": "" }, "require": { @@ -2707,7 +3518,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2715,12 +3526,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, "files": [ "bootstrap.php" ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, "classmap": [ "Resources/stubs" ] @@ -2751,25 +3562,125 @@ "portable", "shim" ], - "time": "2021-01-07T16:49:33+00:00" + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-10T07:21:04+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.2.0", + "version": "v2.5.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1" + "reference": "24d9dc654b83e91aa59f9d167b131bc3b5bea24c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1", - "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/24d9dc654b83e91aa59f9d167b131bc3b5bea24c", + "reference": "24d9dc654b83e91aa59f9d167b131bc3b5bea24c", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/container": "^1.0" + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" }, "suggest": { "symfony/service-implementation": "" @@ -2777,7 +3688,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -2813,20 +3724,37 @@ "interoperability", "standards" ], - "time": "2020-09-07T11:33:47+00:00" + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v2.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-13T20:07:29+00:00" }, { "name": "symfony/string", - "version": "v5.2.1", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed" + "reference": "985e6a9703ef5ce32ba617c9c7d97873bb7b2a99" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed", - "reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed", + "url": "https://api.github.com/repos/symfony/string/zipball/985e6a9703ef5ce32ba617c9c7d97873bb7b2a99", + "reference": "985e6a9703ef5ce32ba617c9c7d97873bb7b2a99", "shasum": "" }, "require": { @@ -2837,20 +3765,23 @@ "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php80": "~1.15" }, + "conflict": { + "symfony/translation-contracts": ">=3.0" + }, "require-dev": { - "symfony/error-handler": "^4.4|^5.0", - "symfony/http-client": "^4.4|^5.0", + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/http-client": "^4.4|^5.0|^6.0", "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0" + "symfony/var-exporter": "^4.4|^5.0|^6.0" }, "type": "library", "autoload": { - "psr-4": { - "Symfony\\Component\\String\\": "" - }, "files": [ "Resources/functions.php" ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, "exclude-from-classmap": [ "/Tests/" ] @@ -2869,7 +3800,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony String component", + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", "homepage": "https://symfony.com", "keywords": [ "grapheme", @@ -2879,25 +3810,43 @@ "utf-8", "utf8" ], - "time": "2020-12-05T07:33:16+00:00" + "support": { + "source": "https://github.com/symfony/string/tree/v5.4.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-04-19T10:40:37+00:00" }, { "name": "symfony/translation", - "version": "v4.4.18", + "version": "v4.4.41", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "c1001b7d75b3136648f94b245588209d881c6939" + "reference": "dcb67eae126e74507e0b4f0b9ac6ef35b37c3331" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/c1001b7d75b3136648f94b245588209d881c6939", - "reference": "c1001b7d75b3136648f94b245588209d881c6939", + "url": "https://api.github.com/repos/symfony/translation/zipball/dcb67eae126e74507e0b4f0b9ac6ef35b37c3331", + "reference": "dcb67eae126e74507e0b4f0b9ac6ef35b37c3331", "shasum": "" }, "require": { "php": ">=7.1.3", "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "^1.16", "symfony/translation-contracts": "^1.1.6|^2" }, "conflict": { @@ -2907,10 +3856,10 @@ "symfony/yaml": "<3.4" }, "provide": { - "symfony/translation-implementation": "1.0" + "symfony/translation-implementation": "1.0|2.0" }, "require-dev": { - "psr/log": "~1.0", + "psr/log": "^1|^2|^3", "symfony/config": "^3.4|^4.0|^5.0", "symfony/console": "^3.4|^4.0|^5.0", "symfony/dependency-injection": "^3.4|^4.0|^5.0", @@ -2948,22 +3897,39 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Translation Component", + "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", - "time": "2020-12-08T16:59:59+00:00" + "support": { + "source": "https://github.com/symfony/translation/tree/v4.4.41" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-04-21T07:22:34+00:00" }, { "name": "symfony/translation-contracts", - "version": "v2.3.0", + "version": "v2.5.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "e2eaa60b558f26a4b0354e1bbb25636efaaad105" + "reference": "1211df0afa701e45a04253110e959d4af4ef0f07" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/e2eaa60b558f26a4b0354e1bbb25636efaaad105", - "reference": "e2eaa60b558f26a4b0354e1bbb25636efaaad105", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/1211df0afa701e45a04253110e959d4af4ef0f07", + "reference": "1211df0afa701e45a04253110e959d4af4ef0f07", "shasum": "" }, "require": { @@ -2975,7 +3941,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -3011,32 +3977,49 @@ "interoperability", "standards" ], - "time": "2020-09-28T13:05:58+00:00" + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v2.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:53:40+00:00" }, { "name": "symfony/yaml", - "version": "v5.2.1", + "version": "v5.4.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "290ea5e03b8cf9b42c783163123f54441fb06939" + "reference": "e80f87d2c9495966768310fc531b487ce64237a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/290ea5e03b8cf9b42c783163123f54441fb06939", - "reference": "290ea5e03b8cf9b42c783163123f54441fb06939", + "url": "https://api.github.com/repos/symfony/yaml/zipball/e80f87d2c9495966768310fc531b487ce64237a2", + "reference": "e80f87d2c9495966768310fc531b487ce64237a2", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-ctype": "~1.8" + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/console": "<4.4" + "symfony/console": "<5.3" }, "require-dev": { - "symfony/console": "^4.4|^5.0" + "symfony/console": "^5.3|^6.0" }, "suggest": { "symfony/console": "For validating YAML files using the lint command" @@ -3067,22 +4050,39 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Yaml Component", + "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", - "time": "2020-12-08T17:02:38+00:00" + "support": { + "source": "https://github.com/symfony/yaml/tree/v5.4.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-26T16:32:32+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "75a63c33a8577608444246075ea0af0d052e452a" + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", - "reference": "75a63c33a8577608444246075ea0af0d052e452a", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", "shasum": "" }, "require": { @@ -3109,34 +4109,49 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "time": "2020-07-12T23:59:07+00:00" + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" }, { "name": "webmozart/assert", - "version": "1.9.1", + "version": "1.11.0", "source": { "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", - "symfony/polyfill-ctype": "^1.8" + "ext-ctype": "*", + "php": "^7.2 || ^8.0" }, "conflict": { "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" + "vimeo/psalm": "<4.6.1 || 4.6.2" }, "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" + "phpunit/phpunit": "^8.5.13" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -3158,7 +4173,11 @@ "check", "validate" ], - "time": "2020-07-08T17:02:28+00:00" + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" } ], "aliases": [], @@ -3167,5 +4186,6 @@ "prefer-stable": false, "prefer-lowest": false, "platform": [], - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "2.1.0" } diff --git a/tests/acceptance/features/bootstrap/FileListContext.php b/tests/acceptance/features/bootstrap/FileListContext.php index ce2bd9971e0..12402c07cc0 100644 --- a/tests/acceptance/features/bootstrap/FileListContext.php +++ b/tests/acceptance/features/bootstrap/FileListContext.php @@ -92,7 +92,7 @@ class FileListContext implements Context, ActorAwareInterface { * @return Locator */ public static function breadcrumbs($fileListAncestor) { - return Locator::forThe()->css("#controls .breadcrumb")-> + return Locator::forThe()->css(".files-controls .breadcrumb")-> descendantOf($fileListAncestor)-> describedAs("Breadcrumbs in file list"); } @@ -101,7 +101,7 @@ class FileListContext implements Context, ActorAwareInterface { * @return Locator */ public static function createMenuButton($fileListAncestor) { - return Locator::forThe()->css("#controls .button.new")-> + return Locator::forThe()->css(".files-controls .button.new")-> descendantOf($fileListAncestor)-> describedAs("Create menu button in file list"); } @@ -186,7 +186,7 @@ class FileListContext implements Context, ActorAwareInterface { * @return Locator */ public static function rowForFile($fileListAncestor, $fileName) { - return Locator::forThe()->xpath("//*[@id = 'fileList']//span[contains(concat(' ', normalize-space(@class), ' '), ' nametext ') and normalize-space() = '$fileName']/ancestor::tr")-> + return Locator::forThe()->xpath("//*[@class = 'files-fileList']//span[contains(concat(' ', normalize-space(@class), ' '), ' nametext ') and normalize-space() = '$fileName']/ancestor::tr")-> descendantOf($fileListAncestor)-> describedAs("Row for file $fileName in file list"); } diff --git a/tests/acceptance/features/bootstrap/FilesAppSharingContext.php b/tests/acceptance/features/bootstrap/FilesAppSharingContext.php index d71b0196dbb..ce3158f9bd9 100644 --- a/tests/acceptance/features/bootstrap/FilesAppSharingContext.php +++ b/tests/acceptance/features/bootstrap/FilesAppSharingContext.php @@ -79,7 +79,7 @@ class FilesAppSharingContext implements Context, ActorAwareInterface { public static function sharedWithRow($sharedWithName) { // "username" class is used for any type of share, not only for shares // with users. - return Locator::forThe()->xpath("//li[contains(concat(' ', normalize-space(@class), ' '), ' sharing-entry ')]//h5[normalize-space() = '$sharedWithName']/ancestor::li")-> + return Locator::forThe()->xpath("//li[contains(concat(' ', normalize-space(@class), ' '), ' sharing-entry ')]//span[normalize-space() = '$sharedWithName']/ancestor::li")-> descendantOf(self::shareeList())-> describedAs("Shared with $sharedWithName row in the details view in Files app"); } diff --git a/tests/acceptance/features/bootstrap/LoginPageContext.php b/tests/acceptance/features/bootstrap/LoginPageContext.php index 7502b143718..3fb06abb235 100644 --- a/tests/acceptance/features/bootstrap/LoginPageContext.php +++ b/tests/acceptance/features/bootstrap/LoginPageContext.php @@ -38,34 +38,22 @@ class LoginPageContext implements Context, ActorAwareInterface { */ private $filesAppContext; - /** - * @return Locator - */ - public static function userNameField() { + public static function userNameField(): Locator { return Locator::forThe()->field("user")-> describedAs("User name field in Login page"); } - /** - * @return Locator - */ - public static function passwordField() { + public static function passwordField(): Locator { return Locator::forThe()->field("password")-> describedAs("Password field in Login page"); } - /** - * @return Locator - */ - public static function loginButton() { - return Locator::forThe()->css(".submit-wrapper .submit-wrapper__input")-> + public static function loginButton(): Locator { + return Locator::forThe()->css(".button-vue[type='submit']")-> describedAs("Login button in Login page"); } - /** - * @return Locator - */ - public static function wrongPasswordMessage() { + public static function wrongPasswordMessage(): Locator { return Locator::forThe()->xpath("//*[@class = 'warning wrongPasswordMsg' and normalize-space() = 'Wrong username or password.']")-> describedAs("Wrong password message in Login page"); } @@ -81,7 +69,7 @@ class LoginPageContext implements Context, ActorAwareInterface { /** * @When I log in with user :user and password :password */ - public function iLogInWithUserAndPassword($user, $password) { + public function iLogInWithUserAndPassword(string $user, string $password): void { $this->actor->find(self::userNameField(), 10)->setValue($user); $this->actor->find(self::passwordField())->setValue($password); $this->actor->find(self::loginButton())->click(); diff --git a/tests/acceptance/features/bootstrap/NotificationsContext.php b/tests/acceptance/features/bootstrap/NotificationsContext.php index 86b17219c03..fb8ca2a354f 100644 --- a/tests/acceptance/features/bootstrap/NotificationsContext.php +++ b/tests/acceptance/features/bootstrap/NotificationsContext.php @@ -30,7 +30,7 @@ class NotificationsContext implements Context, ActorAwareInterface { * @return Locator */ public static function notificationsButton() { - return Locator::forThe()->css("#header .notifications .notifications-button")-> + return Locator::forThe()->css("#header #notifications.notifications-button")-> describedAs("Notifications button in the header"); } @@ -38,7 +38,7 @@ class NotificationsContext implements Context, ActorAwareInterface { * @return Locator */ public static function notificationsContainer() { - return Locator::forThe()->css("#header .notifications .notification-container")-> + return Locator::forThe()->css("#header #notifications .notification-container")-> describedAs("Notifications container"); } diff --git a/tests/acceptance/features/bootstrap/PublicShareContext.php b/tests/acceptance/features/bootstrap/PublicShareContext.php index 2895202ed7f..d31d6541335 100644 --- a/tests/acceptance/features/bootstrap/PublicShareContext.php +++ b/tests/acceptance/features/bootstrap/PublicShareContext.php @@ -48,7 +48,7 @@ class PublicShareContext implements Context, ActorAwareInterface { * @return Locator */ public static function wrongPasswordMessage() { - return Locator::forThe()->xpath("//*[@class = 'warning' and normalize-space() = 'The password is wrong. Try again.']")-> + return Locator::forThe()->css(".warning .wrongPasswordMsg")-> describedAs("Wrong password message in Authenticate page"); } @@ -227,7 +227,7 @@ class PublicShareContext implements Context, ActorAwareInterface { * @Then I see that the shared file preview shows the text :text */ public function iSeeThatTheSharedFilePreviewShowsTheText($text) { - Assert::assertContains($text, $this->actor->find(self::textPreview(), 10)->getText()); + Assert::assertStringContainsString($text, $this->actor->find(self::textPreview(), 10)->getText()); } /** diff --git a/tests/blueprints/basic.toml b/tests/blueprints/basic.toml new file mode 100644 index 00000000000..28902fd5708 --- /dev/null +++ b/tests/blueprints/basic.toml @@ -0,0 +1,20 @@ +[[user]] +id = "test" +groups = ["test_group"] +files = [ + "test.txt", + "foo/sub.png", + "empty", +] + +[[user]] +id = "test2" +groups = ["test"] +files = [ + "many_files/file_[1..100].txt" +] + +[[share]] +from = "test2" +to = "test" +file = "many_files" diff --git a/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js b/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js index 2625a3c3016..a5d6599ef62 100644 --- a/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js +++ b/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js @@ -9,7 +9,6 @@ OC.MimeTypeList={ aliases: { "application/coreldraw": "image", - "application/test": "image", "application/epub+zip": "text", "application/font-sfnt": "image", "application/font-woff": "image", @@ -111,7 +110,11 @@ OC.MimeTypeList={ "application/internet-shortcut": "link", "application/km": "mindmap", "application/x-freemind": "mindmap", - "application/vnd.xmind.workbook": "mindmap" + "application/vnd.xmind.workbook": "mindmap", + "image/targa": "image/tga", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.oform": "x-office/form", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document.docxf": "x-office/form-template", + "my-custom/mimetype": "custom" }, files: [ "application", @@ -137,6 +140,8 @@ OC.MimeTypeList={ "video", "x-office-document", "x-office-drawing", + "x-office-form", + "x-office-form-template", "x-office-presentation", "x-office-spreadsheet" ], diff --git a/tests/data/integritycheck/mimetypeListModified/core/signature.json b/tests/data/integritycheck/mimetypeListModified/core/signature.json new file mode 100644 index 00000000000..c963c416708 --- /dev/null +++ b/tests/data/integritycheck/mimetypeListModified/core/signature.json @@ -0,0 +1,7 @@ +{ + "hashes": { + "core\/js\/mimetypelist.js": "b04161ccafa1fae9ce92393f9e293e70523a7cfde1ffd71ef980a287048fde559d2fd24575652220a821e61ca398b87caab96d533e210c7ee7f48a7cdfcf9bb7" + }, + "signature": "sxNvTR6Y7xfMGFHsHTSYUtBHRtnWb+1ELf4zdgulFv\/4emGrmG2l+oZc+alHIMeBCgWHSrEDmgbtuJ0V6NJCD+yeoGhOJbkqXd9+oFtkIr1ciheg\/AnLnUdSFjmUwsyilVK2VRXIUYsYpRf1gLx0yHoJeif+dZMiNIbgsw3DJn8yNQjwOEFny2ofotV1j79SdSWRvW0PAIaiOMoA0mHyRb95hVL79mHHREpOpfmXStGegXqiHz49ppDrvwG1I3PyjHXl\/2hef5Xn0uzcjk4r5ruVSJB\/dy5pS\/KuxnlrhdwBKl3Lhb0bc5ptwToACIQuWiClr\/lIyqlzdaEWCTYiR8sagvTxS1TzcTgj0gTV3ZCwg+xhMWmkoQ7KBjA9gifgiF\/ADGx+HjgvDH+vZkY1wmima1n3n9muTi+kRmT10zUgtKEAWFCfHH3LoqozSwAqwrLFlU2FYzashK98ip78R6\/+QC23UlqGNDa1i+URWJ8ltksayw047NfhL2isvsfPMLSGeVuqRpg0ht7A4EBKBO2y5cHpEdkHlEbaO7KoV40YKEkYHO5w+EuY\/jmqkENNq\/WRJT4jgzFFdlS3DOUnaHma+oPBas8MTA9PdCb9LDaGYzUyJp+ObBfDxUWGSSRCbYnKAdpqlD+OZMTlpf628LXN64SccN4qkL8AtCZ7Gwk=", + "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" +}
\ No newline at end of file diff --git a/tests/drone-run-php-tests.sh b/tests/drone-run-php-tests.sh index c51117a21d2..ff4737b77a0 100755 --- a/tests/drone-run-php-tests.sh +++ b/tests/drone-run-php-tests.sh @@ -22,4 +22,6 @@ echo "=========================" [[ $(git diff --name-only origin/$DRONE_TARGET_BRANCH...$DRONE_COMMIT_SHA | grep -c "/tests/") -gt 0 ]] && echo "PHP test files of an app are modified" && exit 0 +[[ $(git diff --name-only origin/$DRONE_TARGET_BRANCH...$DRONE_COMMIT_SHA | grep -c "3rdparty") -gt 0 ]] && echo "3rdparty is modified" && exit 0 + exit 1 diff --git a/tests/jestBabelTransformer.js b/tests/jestBabelTransformer.js deleted file mode 100644 index f89ca692a09..00000000000 --- a/tests/jestBabelTransformer.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @copyright 2021 François Freitag <mail@franek.fr> - * - * @author François Freitag <mail@franek.fr> - * - * @license AGPL-3.0-or-later - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - -const babelJest = require('babel-jest') -const babelConfig = require('@nextcloud/babel-config') - -module.exports = babelJest.createTransformer(babelConfig) diff --git a/tests/jestSetup.js b/tests/jestSetup.js index ddc9f378141..c0813ff003f 100644 --- a/tests/jestSetup.js +++ b/tests/jestSetup.js @@ -20,4 +20,4 @@ * */ -require('@testing-library/jest-dom') +import '@testing-library/jest-dom' diff --git a/tests/lib/App/AppStore/Fetcher/AppFetcherTest.php b/tests/lib/App/AppStore/Fetcher/AppFetcherTest.php index 4746c296ab4..a2d56838b07 100644 --- a/tests/lib/App/AppStore/Fetcher/AppFetcherTest.php +++ b/tests/lib/App/AppStore/Fetcher/AppFetcherTest.php @@ -1890,12 +1890,12 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg== $file = $this->createMock(ISimpleFile::class); $folder = $this->createMock(ISimpleFolder::class); $folder - ->expects($this->at(0)) + ->expects($this->once()) ->method('getFile') ->with('apps.json') ->willThrowException(new NotFoundException()); $folder - ->expects($this->at(1)) + ->expects($this->once()) ->method('newFile') ->with('apps.json') ->willReturn($file); @@ -1946,7 +1946,7 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg== } $file - ->expects($this->at(0)) + ->expects($this->once()) ->method('putContent'); $file ->method('getContent') @@ -2017,12 +2017,12 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg== $file = $this->createMock(ISimpleFile::class); $folder = $this->createMock(ISimpleFolder::class); $folder - ->expects($this->at(0)) + ->expects($this->once()) ->method('getFile') ->with('future-apps.json') ->willThrowException(new NotFoundException()); $folder - ->expects($this->at(1)) + ->expects($this->once()) ->method('newFile') ->with('future-apps.json') ->willReturn($file); @@ -2073,7 +2073,7 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg== } $file - ->expects($this->at(0)) + ->expects($this->once()) ->method('putContent'); $file ->method('getContent') @@ -2104,12 +2104,12 @@ EJL3BaQAQaASSsvFrcozYxrQG4VzEg== $file = $this->createMock(ISimpleFile::class); $folder = $this->createMock(ISimpleFolder::class); $folder - ->expects($this->at(0)) + ->expects($this->once()) ->method('getFile') ->with('apps.json') ->willThrowException(new NotFoundException()); $folder - ->expects($this->at(1)) + ->expects($this->once()) ->method('newFile') ->with('apps.json') ->willReturn($file); diff --git a/tests/lib/App/AppStore/Fetcher/FetcherBase.php b/tests/lib/App/AppStore/Fetcher/FetcherBase.php index 87a09cb617d..42ad02ce6d8 100644 --- a/tests/lib/App/AppStore/Fetcher/FetcherBase.php +++ b/tests/lib/App/AppStore/Fetcher/FetcherBase.php @@ -76,22 +76,20 @@ abstract class FetcherBase extends TestCase { public function testGetWithAlreadyExistingFileAndUpToDateTimestampAndVersion() { $this->config - ->expects($this->at(0)) + ->expects($this->once()) ->method('getSystemValueBool') ->with('appstoreenabled', true) ->willReturn(true); $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('has_internet_connection', true) - ->willReturn(true); - $this->config - ->expects($this->at(2)) + ->expects($this->exactly(2)) ->method('getSystemValue') - ->with( - $this->equalTo('version'), - $this->anything() - )->willReturn('11.0.0.2'); + ->withConsecutive( + ['has_internet_connection', true], + [$this->equalTo('version'), $this->anything()], + )->willReturnOnConsecutiveCalls( + true, + '11.0.0.2', + ); $folder = $this->createMock(ISimpleFolder::class); $file = $this->createMock(ISimpleFile::class); @@ -148,12 +146,12 @@ abstract class FetcherBase extends TestCase { ->with('/') ->willReturn($folder); $folder - ->expects($this->at(0)) + ->expects($this->once()) ->method('getFile') ->with($this->fileName) ->willThrowException(new NotFoundException()); $folder - ->expects($this->at(1)) + ->expects($this->once()) ->method('newFile') ->with($this->fileName) ->willReturn($file); @@ -177,15 +175,15 @@ abstract class FetcherBase extends TestCase { ->willReturn('"myETag"'); $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1502,"ncversion":"11.0.0.2","ETag":"\"myETag\""}'; $file - ->expects($this->at(0)) + ->expects($this->once()) ->method('putContent') ->with($fileData); $file - ->expects($this->at(1)) + ->expects($this->once()) ->method('getContent') ->willReturn($fileData); $this->timeFactory - ->expects($this->at(0)) + ->expects($this->once()) ->method('getTime') ->willReturn(1502); @@ -227,14 +225,25 @@ abstract class FetcherBase extends TestCase { ->method('getFile') ->with($this->fileName) ->willReturn($file); + $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1502,"ncversion":"11.0.0.2","ETag":"\"myETag\""}'; $file - ->expects($this->at(0)) + ->expects($this->once()) + ->method('putContent') + ->with($fileData); + $file + ->expects($this->exactly(2)) ->method('getContent') - ->willReturn('{"timestamp":1200,"data":{"MyApp":{"id":"MyApp"}},"ncversion":"11.0.0.2"}'); + ->willReturnOnConsecutiveCalls( + '{"timestamp":1200,"data":{"MyApp":{"id":"MyApp"}},"ncversion":"11.0.0.2"}', + $fileData + ); $this->timeFactory - ->expects($this->at(0)) + ->expects($this->exactly(2)) ->method('getTime') - ->willReturn(4801); + ->willReturnOnConsecutiveCalls( + 4801, + 1502 + ); $client = $this->createMock(IClient::class); $this->clientService ->expects($this->once()) @@ -253,19 +262,6 @@ abstract class FetcherBase extends TestCase { $response->method('getHeader') ->with($this->equalTo('ETag')) ->willReturn('"myETag"'); - $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1502,"ncversion":"11.0.0.2","ETag":"\"myETag\""}'; - $file - ->expects($this->at(1)) - ->method('putContent') - ->with($fileData); - $file - ->expects($this->at(2)) - ->method('getContent') - ->willReturn($fileData); - $this->timeFactory - ->expects($this->at(1)) - ->method('getTime') - ->willReturn(1502); $expected = [ [ @@ -309,12 +305,20 @@ abstract class FetcherBase extends TestCase { ->method('getFile') ->with($this->fileName) ->willReturn($file); + $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1201,"ncversion":"11.0.0.2","ETag":"\"myETag\""}'; + $file + ->expects($this->once()) + ->method('putContent') + ->with($fileData); $file - ->expects($this->at(0)) + ->expects($this->exactly(2)) ->method('getContent') - ->willReturn('{"timestamp":1200,"data":{"MyApp":{"id":"MyApp"}}'); + ->willReturnOnConsecutiveCalls( + '{"timestamp":1200,"data":{"MyApp":{"id":"MyApp"}}', + $fileData + ); $this->timeFactory - ->expects($this->at(0)) + ->expects($this->once()) ->method('getTime') ->willReturn(1201); $client = $this->createMock(IClient::class); @@ -335,15 +339,6 @@ abstract class FetcherBase extends TestCase { $response->method('getHeader') ->with($this->equalTo('ETag')) ->willReturn('"myETag"'); - $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1201,"ncversion":"11.0.0.2","ETag":"\"myETag\""}'; - $file - ->expects($this->at(1)) - ->method('putContent') - ->with($fileData); - $file - ->expects($this->at(2)) - ->method('getContent') - ->willReturn($fileData); $expected = [ [ @@ -387,10 +382,18 @@ abstract class FetcherBase extends TestCase { ->method('getFile') ->with($this->fileName) ->willReturn($file); + $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1201,"ncversion":"11.0.0.2","ETag":"\"myETag\""}'; + $file + ->expects($this->once()) + ->method('putContent') + ->with($fileData); $file - ->expects($this->at(0)) + ->expects($this->exactly(2)) ->method('getContent') - ->willReturn('{"timestamp":1200,"data":{"MyApp":{"id":"MyApp"}},"ncversion":"11.0.0.1"'); + ->willReturnOnConsecutiveCalls( + '{"timestamp":1200,"data":{"MyApp":{"id":"MyApp"}},"ncversion":"11.0.0.1"', + $fileData + ); $this->timeFactory ->method('getTime') ->willReturn(1201); @@ -412,15 +415,6 @@ abstract class FetcherBase extends TestCase { $response->method('getHeader') ->with($this->equalTo('ETag')) ->willReturn('"myETag"'); - $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1201,"ncversion":"11.0.0.2","ETag":"\"myETag\""}'; - $file - ->expects($this->at(1)) - ->method('putContent') - ->with($fileData); - $file - ->expects($this->at(2)) - ->method('getContent') - ->willReturn($fileData); $expected = [ [ @@ -457,7 +451,7 @@ abstract class FetcherBase extends TestCase { ->with($this->fileName) ->willReturn($file); $file - ->expects($this->at(0)) + ->expects($this->once()) ->method('getContent') ->willReturn('{"timestamp":1200,"data":{"MyApp":{"id":"MyApp"}}}'); $client = $this->createMock(IClient::class); @@ -501,18 +495,26 @@ abstract class FetcherBase extends TestCase { ->with($this->fileName) ->willReturn($file); $origData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1200,"ncversion":"11.0.0.2","ETag":"\"myETag\""}'; + + $newData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":4802,"ncversion":"11.0.0.2","ETag":"\"myETag\""}'; $file - ->expects($this->at(0)) + ->expects($this->once()) + ->method('putContent') + ->with($newData); + $file + ->expects($this->exactly(2)) ->method('getContent') - ->willReturn($origData); - $this->timeFactory - ->expects($this->at(0)) - ->method('getTime') - ->willReturn(4801); + ->willReturnOnConsecutiveCalls( + $origData, + $newData, + ); $this->timeFactory - ->expects($this->at(1)) + ->expects($this->exactly(2)) ->method('getTime') - ->willReturn(4802); + ->willReturnOnConsecutiveCalls( + 4801, + 4802 + ); $client = $this->createMock(IClient::class); $this->clientService ->expects($this->once()) @@ -534,16 +536,6 @@ abstract class FetcherBase extends TestCase { $response->method('getStatusCode') ->willReturn(304); - $newData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":4802,"ncversion":"11.0.0.2","ETag":"\"myETag\""}'; - $file - ->expects($this->at(1)) - ->method('putContent') - ->with($newData); - $file - ->expects($this->at(2)) - ->method('getContent') - ->willReturn($newData); - $expected = [ [ 'id' => 'MyNewApp', @@ -579,14 +571,29 @@ abstract class FetcherBase extends TestCase { ->with('/') ->willReturn($folder); $folder - ->expects($this->at(0)) + ->expects($this->once()) ->method('getFile') ->with($this->fileName) ->willReturn($file); + $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":4802,"ncversion":"11.0.0.2","ETag":"\"newETag\""}'; $file - ->expects($this->at(0)) + ->expects($this->once()) + ->method('putContent') + ->with($fileData); + $file + ->expects($this->exactly(2)) ->method('getContent') - ->willReturn('{"data":[{"id":"MyOldApp","abc":"def"}],"timestamp":1200,"ncversion":"11.0.0.2","ETag":"\"myETag\""}'); + ->willReturnOnConsecutiveCalls( + '{"data":[{"id":"MyOldApp","abc":"def"}],"timestamp":1200,"ncversion":"11.0.0.2","ETag":"\"myETag\""}', + $fileData, + ); + $this->timeFactory + ->expects($this->exactly(2)) + ->method('getTime') + ->willReturnOnConsecutiveCalls( + 4801, + 4802, + ); $client = $this->createMock(IClient::class); $this->clientService ->expects($this->once()) @@ -615,23 +622,6 @@ abstract class FetcherBase extends TestCase { $response->method('getHeader') ->with($this->equalTo('ETag')) ->willReturn('"newETag"'); - $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":4802,"ncversion":"11.0.0.2","ETag":"\"newETag\""}'; - $file - ->expects($this->at(1)) - ->method('putContent') - ->with($fileData); - $file - ->expects($this->at(2)) - ->method('getContent') - ->willReturn($fileData); - $this->timeFactory - ->expects($this->at(0)) - ->method('getTime') - ->willReturn(4801); - $this->timeFactory - ->expects($this->at(1)) - ->method('getTime') - ->willReturn(4802); $expected = [ [ @@ -668,14 +658,22 @@ abstract class FetcherBase extends TestCase { ->with('/') ->willReturn($folder); $folder - ->expects($this->at(0)) + ->expects($this->once()) ->method('getFile') ->with($this->fileName) ->willReturn($file); + $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1501,"ncversion":"11.0.0.3","ETag":"\"newETag\""}'; + $file + ->expects($this->once()) + ->method('putContent') + ->with($fileData); $file - ->expects($this->at(0)) + ->expects($this->exactly(2)) ->method('getContent') - ->willReturn('{"data":[{"id":"MyOldApp","abc":"def"}],"timestamp":1200,"ncversion":"11.0.0.2","ETag":"\"myETag\""}'); + ->willReturnOnConsecutiveCalls( + '{"data":[{"id":"MyOldApp","abc":"def"}],"timestamp":1200,"ncversion":"11.0.0.2","ETag":"\"myETag\""}', + $fileData + ); $client = $this->createMock(IClient::class); $this->clientService ->expects($this->once()) @@ -701,15 +699,6 @@ abstract class FetcherBase extends TestCase { $response->method('getHeader') ->with($this->equalTo('ETag')) ->willReturn('"newETag"'); - $fileData = '{"data":[{"id":"MyNewApp","foo":"foo"},{"id":"bar"}],"timestamp":1501,"ncversion":"11.0.0.3","ETag":"\"newETag\""}'; - $file - ->expects($this->at(1)) - ->method('putContent') - ->with($fileData); - $file - ->expects($this->at(2)) - ->method('getContent') - ->willReturn($fileData); $this->timeFactory ->expects($this->once()) ->method('getTime') diff --git a/tests/lib/App/InfoParserTest.php b/tests/lib/App/InfoParserTest.php index 8de0f4cfd4f..bc561611501 100644 --- a/tests/lib/App/InfoParserTest.php +++ b/tests/lib/App/InfoParserTest.php @@ -11,16 +11,16 @@ namespace Test\App; use OC; use OC\App\InfoParser; use Test\TestCase; +use OCP\Cache\CappedMemoryCache; class InfoParserTest extends TestCase { - /** @var OC\Cache\CappedMemoryCache */ + /** @var OCP\Cache\CappedMemoryCache */ private static $cache; public static function setUpBeforeClass(): void { - self::$cache = new OC\Cache\CappedMemoryCache(); + self::$cache = new CappedMemoryCache(); } - public function parserTest($expectedJson, $xmlFile, $cache = null) { $parser = new InfoParser($cache); diff --git a/tests/lib/AppFramework/Db/EntityTest.php b/tests/lib/AppFramework/Db/EntityTest.php index 17234849a2d..d76a8ccfe06 100644 --- a/tests/lib/AppFramework/Db/EntityTest.php +++ b/tests/lib/AppFramework/Db/EntityTest.php @@ -43,6 +43,8 @@ use PHPUnit\Framework\Constraint\IsType; * @method bool getAnotherBool() * @method bool isAnotherBool() * @method void setAnotherBool(bool $anotherBool) + * @method string getLongText() + * @method void setLongText(string $longText) */ class TestEntity extends Entity { protected $name; @@ -51,11 +53,13 @@ class TestEntity extends Entity { protected $preName; protected $trueOrFalse; protected $anotherBool; + protected $longText; public function __construct($name = null) { $this->addType('testId', 'integer'); $this->addType('trueOrFalse', 'bool'); $this->addType('anotherBool', 'boolean'); + $this->addType('longText', 'blob'); $this->name = $name; } } @@ -210,6 +214,18 @@ class EntityTest extends \Test\TestCase { $this->assertSame(null, $entity->getId()); } + public function testSetterConvertsResourcesToStringProperly() { + $string = 'Definitely a string'; + $stream = fopen('php://memory', 'r+'); + fwrite($stream, $string); + rewind($stream); + + $entity = new TestEntity(); + $entity->setLongText($stream); + fclose($stream); + $this->assertSame($string, $entity->getLongText()); + } + public function testGetFieldTypes() { $entity = new TestEntity(); @@ -218,6 +234,7 @@ class EntityTest extends \Test\TestCase { 'testId' => 'integer', 'trueOrFalse' => 'bool', 'anotherBool' => 'boolean', + 'longText' => 'blob', ], $entity->getFieldTypes()); } diff --git a/tests/lib/AppFramework/Http/DispatcherTest.php b/tests/lib/AppFramework/Http/DispatcherTest.php index e1d78082a2d..8f591f26e58 100644 --- a/tests/lib/AppFramework/Http/DispatcherTest.php +++ b/tests/lib/AppFramework/Http/DispatcherTest.php @@ -89,6 +89,8 @@ class DispatcherTest extends \Test\TestCase { /** @var Dispatcher */ private $dispatcher; private $controllerMethod; + /** @var Controller|MockObject */ + private $controller; private $response; /** @var IRequest|MockObject */ private $request; diff --git a/tests/lib/AppFramework/Http/JSONResponseTest.php b/tests/lib/AppFramework/Http/JSONResponseTest.php index 504876b2d88..8c8318eb602 100644 --- a/tests/lib/AppFramework/Http/JSONResponseTest.php +++ b/tests/lib/AppFramework/Http/JSONResponseTest.php @@ -88,10 +88,10 @@ class JSONResponseTest extends \Test\TestCase { $this->assertEquals($expected, $this->json->render()); } - + public function testRenderWithNonUtf8Encoding() { - $this->expectException(\Exception::class); - $this->expectExceptionMessage('Could not json_encode due to invalid non UTF-8 characters in the array: array ('); + $this->expectException(\JsonException::class); + $this->expectExceptionMessage('Malformed UTF-8 characters, possibly incorrectly encoded'); $params = ['test' => hex2bin('e9')]; $this->json->setData($params); diff --git a/tests/lib/AppFramework/Http/RequestTest.php b/tests/lib/AppFramework/Http/RequestTest.php index e15f3fe656c..cf5ebdca2f0 100644 --- a/tests/lib/AppFramework/Http/RequestTest.php +++ b/tests/lib/AppFramework/Http/RequestTest.php @@ -381,15 +381,15 @@ class RequestTest extends \Test\TestCase { public function testGetRemoteAddressWithNoTrustedHeader() { $this->config - ->expects($this->at(0)) + ->expects($this->exactly(2)) ->method('getSystemValue') - ->with('trusted_proxies') - ->willReturn(['10.0.0.2']); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('forwarded_for_headers') - ->willReturn([]); + ->withConsecutive( + ['trusted_proxies'], + ['forwarded_for_headers'], + )->willReturnOnConsecutiveCalls( + ['10.0.0.2'], + [] + ); $request = new Request( [ @@ -410,15 +410,15 @@ class RequestTest extends \Test\TestCase { public function testGetRemoteAddressWithSingleTrustedRemote() { $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('trusted_proxies') - ->willReturn(['10.0.0.2']); - $this->config - ->expects($this->at(1)) + ->expects($this->exactly(2)) ->method('getSystemValue') - ->with('forwarded_for_headers') - ->willReturn(['HTTP_X_FORWARDED']); + ->withConsecutive( + ['trusted_proxies'], + ['forwarded_for_headers'], + )-> willReturnOnConsecutiveCalls( + ['10.0.0.2'], + ['HTTP_X_FORWARDED'], + ); $request = new Request( [ @@ -439,15 +439,15 @@ class RequestTest extends \Test\TestCase { public function testGetRemoteAddressIPv6WithSingleTrustedRemote() { $this->config - ->expects($this->at(0)) + ->expects($this->exactly(2)) ->method('getSystemValue') - ->with('trusted_proxies') - ->willReturn(['2001:db8:85a3:8d3:1319:8a2e:370:7348']); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('forwarded_for_headers') - ->willReturn(['HTTP_X_FORWARDED']); + ->withConsecutive( + ['trusted_proxies'], + ['forwarded_for_headers'], + )-> willReturnOnConsecutiveCalls( + ['2001:db8:85a3:8d3:1319:8a2e:370:7348'], + ['HTTP_X_FORWARDED'], + ); $request = new Request( [ @@ -468,19 +468,19 @@ class RequestTest extends \Test\TestCase { public function testGetRemoteAddressVerifyPriorityHeader() { $this->config - ->expects($this->at(0)) + ->expects($this->exactly(2)) ->method('getSystemValue') - ->with('trusted_proxies') - ->willReturn(['10.0.0.2']); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('forwarded_for_headers') - ->willReturn([ - 'HTTP_CLIENT_IP', - 'HTTP_X_FORWARDED_FOR', - 'HTTP_X_FORWARDED' - ]); + ->withConsecutive( + ['trusted_proxies'], + ['forwarded_for_headers'], + )-> willReturnOnConsecutiveCalls( + ['10.0.0.2'], + [ + 'HTTP_CLIENT_IP', + 'HTTP_X_FORWARDED_FOR', + 'HTTP_X_FORWARDED', + ], + ); $request = new Request( [ @@ -501,19 +501,19 @@ class RequestTest extends \Test\TestCase { public function testGetRemoteAddressIPv6VerifyPriorityHeader() { $this->config - ->expects($this->at(0)) + ->expects($this->exactly(2)) ->method('getSystemValue') - ->with('trusted_proxies') - ->willReturn(['2001:db8:85a3:8d3:1319:8a2e:370:7348']); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('forwarded_for_headers') - ->willReturn([ - 'HTTP_CLIENT_IP', - 'HTTP_X_FORWARDED_FOR', - 'HTTP_X_FORWARDED' - ]); + ->withConsecutive( + ['trusted_proxies'], + ['forwarded_for_headers'], + )-> willReturnOnConsecutiveCalls( + ['2001:db8:85a3:8d3:1319:8a2e:370:7348'], + [ + 'HTTP_CLIENT_IP', + 'HTTP_X_FORWARDED_FOR', + 'HTTP_X_FORWARDED' + ], + ); $request = new Request( [ @@ -534,15 +534,15 @@ class RequestTest extends \Test\TestCase { public function testGetRemoteAddressWithMatchingCidrTrustedRemote() { $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('trusted_proxies') - ->willReturn(['192.168.2.0/24']); - $this->config - ->expects($this->at(1)) + ->expects($this->exactly(2)) ->method('getSystemValue') - ->with('forwarded_for_headers') - ->willReturn(['HTTP_X_FORWARDED_FOR']); + ->withConsecutive( + ['trusted_proxies'], + ['forwarded_for_headers'], + )-> willReturnOnConsecutiveCalls( + ['192.168.2.0/24'], + ['HTTP_X_FORWARDED_FOR'], + ); $request = new Request( [ @@ -585,17 +585,94 @@ class RequestTest extends \Test\TestCase { $this->assertSame('192.168.3.99', $request->getRemoteAddress()); } - public function testGetRemoteAddressWithXForwardedForIPv6() { + public function testGetRemoteIpv6AddressWithMatchingIpv6CidrTrustedRemote() { $this->config - ->expects($this->at(0)) + ->expects($this->exactly(2)) + ->method('getSystemValue') + ->withConsecutive( + ['trusted_proxies'], + ['forwarded_for_headers'] + )->willReturnOnConsecutiveCalls( + ['2001:db8:85a3:8d3:1319:8a20::/95'], + ['HTTP_X_FORWARDED_FOR'] + ); + + $request = new Request( + [ + 'server' => [ + 'REMOTE_ADDR' => '2001:db8:85a3:8d3:1319:8a21:370:7348', + 'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4', + 'HTTP_X_FORWARDED_FOR' => '192.168.0.233' + ], + ], + $this->requestId, + $this->config, + $this->csrfTokenManager, + $this->stream + ); + + $this->assertSame('192.168.0.233', $request->getRemoteAddress()); + } + + public function testGetRemoteAddressIpv6WithNotMatchingCidrTrustedRemote() { + $this->config + ->expects($this->once()) ->method('getSystemValue') ->with('trusted_proxies') - ->willReturn(['192.168.2.0/24']); + ->willReturn(['fd::/8']); + + $request = new Request( + [ + 'server' => [ + 'REMOTE_ADDR' => '2001:db8:85a3:8d3:1319:8a2e:370:7348', + 'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4', + 'HTTP_X_FORWARDED_FOR' => '192.168.0.233' + ], + ], + $this->requestId, + $this->config, + $this->csrfTokenManager, + $this->stream + ); + + $this->assertSame('2001:db8:85a3:8d3:1319:8a2e:370:7348', $request->getRemoteAddress()); + } + + public function testGetRemoteAddressIpv6WithInvalidTrustedProxy() { + $this->config + ->expects($this->once()) + ->method('getSystemValue') + ->with('trusted_proxies') + ->willReturn(['fx::/8']); + + $request = new Request( + [ + 'server' => [ + 'REMOTE_ADDR' => '2001:db8:85a3:8d3:1319:8a2e:370:7348', + 'HTTP_X_FORWARDED' => '10.4.0.5, 10.4.0.4', + 'HTTP_X_FORWARDED_FOR' => '192.168.0.233' + ], + ], + $this->requestId, + $this->config, + $this->csrfTokenManager, + $this->stream + ); + + $this->assertSame('2001:db8:85a3:8d3:1319:8a2e:370:7348', $request->getRemoteAddress()); + } + + public function testGetRemoteAddressWithXForwardedForIPv6() { $this->config - ->expects($this->at(1)) + ->expects($this->exactly(2)) ->method('getSystemValue') - ->with('forwarded_for_headers') - ->willReturn(['HTTP_X_FORWARDED_FOR']); + ->withConsecutive( + ['trusted_proxies'], + ['forwarded_for_headers'], + )-> willReturnOnConsecutiveCalls( + ['192.168.2.0/24'], + ['HTTP_X_FORWARDED_FOR'], + ); $request = new Request( [ @@ -666,20 +743,12 @@ class RequestTest extends \Test\TestCase { public function testGetServerProtocolWithOverride() { $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('overwriteprotocol') - ->willReturn('customProtocol'); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('overwritecondaddr') - ->willReturn(''); - $this->config - ->expects($this->at(2)) + ->expects($this->exactly(3)) ->method('getSystemValue') - ->with('overwriteprotocol') - ->willReturn('customProtocol'); + ->willReturnMap([ + ['overwriteprotocol', '', 'customProtocol'], + ['overwritecondaddr', '', ''], + ]); $request = new Request( [], @@ -1266,20 +1335,12 @@ class RequestTest extends \Test\TestCase { public function testGetOverwriteHostWithOverwrite() { $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('overwritehost') - ->willReturn('www.owncloud.org'); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('overwritecondaddr') - ->willReturn(''); - $this->config - ->expects($this->at(2)) + ->expects($this->exactly(3)) ->method('getSystemValue') - ->with('overwritehost') - ->willReturn('www.owncloud.org'); + ->willReturnMap([ + ['overwritehost', '', 'www.owncloud.org'], + ['overwritecondaddr', '', ''], + ]); $request = new Request( [], @@ -1493,15 +1554,12 @@ class RequestTest extends \Test\TestCase { */ public function testGetRequestUriWithOverwrite($expectedUri, $overwriteWebRoot, $overwriteCondAddr) { $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with('overwritewebroot') - ->willReturn($overwriteWebRoot); - $this->config - ->expects($this->at(1)) + ->expects($this->exactly(2)) ->method('getSystemValue') - ->with('overwritecondaddr') - ->willReturn($overwriteCondAddr); + ->willReturnMap([ + ['overwritewebroot', '', $overwriteWebRoot], + ['overwritecondaddr', '', $overwriteCondAddr], + ]); $request = $this->getMockBuilder('\OC\AppFramework\Http\Request') ->setMethods(['getScriptName']) diff --git a/tests/lib/AppFramework/Middleware/Security/BruteForceMiddlewareTest.php b/tests/lib/AppFramework/Middleware/Security/BruteForceMiddlewareTest.php index cc04992ae18..7dfcfe22261 100644 --- a/tests/lib/AppFramework/Middleware/Security/BruteForceMiddlewareTest.php +++ b/tests/lib/AppFramework/Middleware/Security/BruteForceMiddlewareTest.php @@ -36,8 +36,7 @@ class BruteForceMiddlewareTest extends TestCase { private $throttler; /** @var IRequest|\PHPUnit\Framework\MockObject\MockObject */ private $request; - /** @var BruteForceMiddleware */ - private $bruteForceMiddleware; + private BruteForceMiddleware $bruteForceMiddleware; protected function setUp(): void { parent::setUp(); diff --git a/tests/lib/AppFramework/Middleware/Security/RateLimitingMiddlewareTest.php b/tests/lib/AppFramework/Middleware/Security/RateLimitingMiddlewareTest.php index aa713b99156..38d01950f6a 100644 --- a/tests/lib/AppFramework/Middleware/Security/RateLimitingMiddlewareTest.php +++ b/tests/lib/AppFramework/Middleware/Security/RateLimitingMiddlewareTest.php @@ -66,25 +66,20 @@ class RateLimitingMiddlewareTest extends TestCase { public function testBeforeControllerWithoutAnnotation() { $this->reflector - ->expects($this->at(0)) + ->expects($this->exactly(4)) ->method('getAnnotationParameter') - ->with('AnonRateThrottle', 'limit') - ->willReturn(''); - $this->reflector - ->expects($this->at(1)) - ->method('getAnnotationParameter') - ->with('AnonRateThrottle', 'period') - ->willReturn(''); - $this->reflector - ->expects($this->at(2)) - ->method('getAnnotationParameter') - ->with('UserRateThrottle', 'limit') - ->willReturn(''); - $this->reflector - ->expects($this->at(3)) - ->method('getAnnotationParameter') - ->with('UserRateThrottle', 'period') - ->willReturn(''); + ->withConsecutive( + ['AnonRateThrottle', 'limit'], + ['AnonRateThrottle', 'period'], + ['UserRateThrottle', 'limit'], + ['UserRateThrottle', 'period'] + ) + ->willReturnMap([ + ['AnonRateThrottle', 'limit', ''], + ['AnonRateThrottle', 'period', ''], + ['UserRateThrottle', 'limit', ''], + ['UserRateThrottle', 'period', ''], + ]); $this->limiter ->expects($this->never()) @@ -107,25 +102,20 @@ class RateLimitingMiddlewareTest extends TestCase { ->willReturn('127.0.0.1'); $this->reflector - ->expects($this->at(0)) - ->method('getAnnotationParameter') - ->with('AnonRateThrottle', 'limit') - ->willReturn('100'); - $this->reflector - ->expects($this->at(1)) - ->method('getAnnotationParameter') - ->with('AnonRateThrottle', 'period') - ->willReturn('10'); - $this->reflector - ->expects($this->at(2)) - ->method('getAnnotationParameter') - ->with('UserRateThrottle', 'limit') - ->willReturn(''); - $this->reflector - ->expects($this->at(3)) + ->expects($this->exactly(4)) ->method('getAnnotationParameter') - ->with('UserRateThrottle', 'period') - ->willReturn(''); + ->withConsecutive( + ['AnonRateThrottle', 'limit'], + ['AnonRateThrottle', 'period'], + ['UserRateThrottle', 'limit'], + ['UserRateThrottle', 'period'] + ) + ->willReturnMap([ + ['AnonRateThrottle', 'limit', '100'], + ['AnonRateThrottle', 'period', '10'], + ['UserRateThrottle', 'limit', ''], + ['UserRateThrottle', 'period', ''], + ]); $this->limiter ->expects($this->never()) @@ -155,25 +145,20 @@ class RateLimitingMiddlewareTest extends TestCase { ->willReturn($user); $this->reflector - ->expects($this->at(0)) + ->expects($this->exactly(4)) ->method('getAnnotationParameter') - ->with('AnonRateThrottle', 'limit') - ->willReturn(''); - $this->reflector - ->expects($this->at(1)) - ->method('getAnnotationParameter') - ->with('AnonRateThrottle', 'period') - ->willReturn(''); - $this->reflector - ->expects($this->at(2)) - ->method('getAnnotationParameter') - ->with('UserRateThrottle', 'limit') - ->willReturn('100'); - $this->reflector - ->expects($this->at(3)) - ->method('getAnnotationParameter') - ->with('UserRateThrottle', 'period') - ->willReturn('10'); + ->withConsecutive( + ['AnonRateThrottle', 'limit'], + ['AnonRateThrottle', 'period'], + ['UserRateThrottle', 'limit'], + ['UserRateThrottle', 'period'] + ) + ->willReturnMap([ + ['AnonRateThrottle', 'limit', ''], + ['AnonRateThrottle', 'period', ''], + ['UserRateThrottle', 'limit', '100'], + ['UserRateThrottle', 'period', '10'], + ]); $this->limiter ->expects($this->never()) @@ -201,25 +186,20 @@ class RateLimitingMiddlewareTest extends TestCase { ->willReturn(false); $this->reflector - ->expects($this->at(0)) - ->method('getAnnotationParameter') - ->with('AnonRateThrottle', 'limit') - ->willReturn('200'); - $this->reflector - ->expects($this->at(1)) - ->method('getAnnotationParameter') - ->with('AnonRateThrottle', 'period') - ->willReturn('20'); - $this->reflector - ->expects($this->at(2)) - ->method('getAnnotationParameter') - ->with('UserRateThrottle', 'limit') - ->willReturn('100'); - $this->reflector - ->expects($this->at(3)) + ->expects($this->exactly(4)) ->method('getAnnotationParameter') - ->with('UserRateThrottle', 'period') - ->willReturn('10'); + ->withConsecutive( + ['AnonRateThrottle', 'limit'], + ['AnonRateThrottle', 'period'], + ['UserRateThrottle', 'limit'], + ['UserRateThrottle', 'period'] + ) + ->willReturnMap([ + ['AnonRateThrottle', 'limit', '200'], + ['AnonRateThrottle', 'period', '20'], + ['UserRateThrottle', 'limit', '100'], + ['UserRateThrottle', 'period', '10'], + ]); $this->limiter ->expects($this->never()) diff --git a/tests/lib/AppFramework/Routing/RoutingTest.php b/tests/lib/AppFramework/Routing/RoutingTest.php index b4965d61d4f..22037c31d0d 100644 --- a/tests/lib/AppFramework/Routing/RoutingTest.php +++ b/tests/lib/AppFramework/Routing/RoutingTest.php @@ -304,36 +304,23 @@ class RoutingTest extends \Test\TestCase { $urlWithParam = $url . '/{' . $paramName . '}'; - // we expect create to be called once: - $router - ->expects($this->at(0)) - ->method('create') - ->with($this->equalTo('ocs.app1.' . $resourceName . '.index'), $this->equalTo($url)) - ->willReturn($indexRoute); - - $router - ->expects($this->at(1)) - ->method('create') - ->with($this->equalTo('ocs.app1.' . $resourceName . '.show'), $this->equalTo($urlWithParam)) - ->willReturn($showRoute); - - $router - ->expects($this->at(2)) - ->method('create') - ->with($this->equalTo('ocs.app1.' . $resourceName . '.create'), $this->equalTo($url)) - ->willReturn($createRoute); - - $router - ->expects($this->at(3)) - ->method('create') - ->with($this->equalTo('ocs.app1.' . $resourceName . '.update'), $this->equalTo($urlWithParam)) - ->willReturn($updateRoute); - + // we expect create to be called five times: $router - ->expects($this->at(4)) + ->expects($this->exactly(5)) ->method('create') - ->with($this->equalTo('ocs.app1.' . $resourceName . '.destroy'), $this->equalTo($urlWithParam)) - ->willReturn($destroyRoute); + ->withConsecutive( + [$this->equalTo('ocs.app1.' . $resourceName . '.index'), $this->equalTo($url)], + [$this->equalTo('ocs.app1.' . $resourceName . '.show'), $this->equalTo($urlWithParam)], + [$this->equalTo('ocs.app1.' . $resourceName . '.create'), $this->equalTo($url)], + [$this->equalTo('ocs.app1.' . $resourceName . '.update'), $this->equalTo($urlWithParam)], + [$this->equalTo('ocs.app1.' . $resourceName . '.destroy'), $this->equalTo($urlWithParam)], + )->willReturnOnConsecutiveCalls( + $indexRoute, + $showRoute, + $createRoute, + $updateRoute, + $destroyRoute, + ); // load route configuration $config = new RouteConfig($container, $router, $yaml); @@ -364,36 +351,23 @@ class RoutingTest extends \Test\TestCase { $urlWithParam = $url . '/{' . $paramName . '}'; - // we expect create to be called once: - $router - ->expects($this->at(0)) - ->method('create') - ->with($this->equalTo('app1.' . $resourceName . '.index'), $this->equalTo($url)) - ->willReturn($indexRoute); - - $router - ->expects($this->at(1)) - ->method('create') - ->with($this->equalTo('app1.' . $resourceName . '.show'), $this->equalTo($urlWithParam)) - ->willReturn($showRoute); - - $router - ->expects($this->at(2)) - ->method('create') - ->with($this->equalTo('app1.' . $resourceName . '.create'), $this->equalTo($url)) - ->willReturn($createRoute); - - $router - ->expects($this->at(3)) - ->method('create') - ->with($this->equalTo('app1.' . $resourceName . '.update'), $this->equalTo($urlWithParam)) - ->willReturn($updateRoute); - + // we expect create to be called five times: $router - ->expects($this->at(4)) + ->expects($this->exactly(5)) ->method('create') - ->with($this->equalTo('app1.' . $resourceName . '.destroy'), $this->equalTo($urlWithParam)) - ->willReturn($destroyRoute); + ->withConsecutive( + [$this->equalTo('app1.' . $resourceName . '.index'), $this->equalTo($url)], + [$this->equalTo('app1.' . $resourceName . '.show'), $this->equalTo($urlWithParam)], + [$this->equalTo('app1.' . $resourceName . '.create'), $this->equalTo($url)], + [$this->equalTo('app1.' . $resourceName . '.update'), $this->equalTo($urlWithParam)], + [$this->equalTo('app1.' . $resourceName . '.destroy'), $this->equalTo($urlWithParam)], + )->willReturnOnConsecutiveCalls( + $indexRoute, + $showRoute, + $createRoute, + $updateRoute, + $destroyRoute, + ); // load route configuration $config = new RouteConfig($container, $router, $yaml); diff --git a/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php b/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php index 6ad57515c16..1ef0aa80817 100644 --- a/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php +++ b/tests/lib/Authentication/Token/PublicKeyTokenProviderTest.php @@ -25,6 +25,7 @@ namespace Test\Authentication\Token; use OC\Authentication\Exceptions\ExpiredTokenException; use OC\Authentication\Exceptions\InvalidTokenException; +use OC\Authentication\Exceptions\PasswordlessTokenException; use OC\Authentication\Token\IToken; use OC\Authentication\Token\PublicKeyToken; use OC\Authentication\Token\PublicKeyTokenMapper; @@ -83,6 +84,10 @@ class PublicKeyTokenProviderTest extends TestCase { $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'; $type = IToken::PERMANENT_TOKEN; + $this->config->method('getSystemValueBool') + ->willReturnMap([ + ['auth.storeCryptedPassword', true, true], + ]); $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER); $this->assertInstanceOf(PublicKeyToken::class, $actual); @@ -93,6 +98,48 @@ class PublicKeyTokenProviderTest extends TestCase { $this->assertSame($password, $this->tokenProvider->getPassword($actual, $token)); } + public function testGenerateTokenNoPassword(): void { + $token = 'token'; + $uid = 'user'; + $user = 'User'; + $password = 'passme'; + $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'; + $type = IToken::PERMANENT_TOKEN; + $this->config->method('getSystemValueBool') + ->willReturnMap([ + ['auth.storeCryptedPassword', true, false], + ]); + $this->expectException(PasswordlessTokenException::class); + + $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER); + + $this->assertInstanceOf(PublicKeyToken::class, $actual); + $this->assertSame($uid, $actual->getUID()); + $this->assertSame($user, $actual->getLoginName()); + $this->assertSame($name, $actual->getName()); + $this->assertSame(IToken::DO_NOT_REMEMBER, $actual->getRemember()); + $this->tokenProvider->getPassword($actual, $token); + } + + public function testGenerateTokenLongPassword() { + $token = 'token'; + $uid = 'user'; + $user = 'User'; + $password = ''; + for ($i = 0; $i < 500; $i++) { + $password .= 'e'; + } + $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'; + $type = IToken::PERMANENT_TOKEN; + $this->config->method('getSystemValueBool') + ->willReturnMap([ + ['auth.storeCryptedPassword', true, true], + ]); + $this->expectException(\RuntimeException::class); + + $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER); + } + public function testGenerateTokenInvalidName() { $token = 'token'; $uid = 'user'; @@ -103,6 +150,10 @@ class PublicKeyTokenProviderTest extends TestCase { . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12' . 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'; $type = IToken::PERMANENT_TOKEN; + $this->config->method('getSystemValueBool') + ->willReturnMap([ + ['auth.storeCryptedPassword', true, true], + ]); $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER); @@ -120,6 +171,10 @@ class PublicKeyTokenProviderTest extends TestCase { ->method('updateActivity') ->with($tk, $this->time); $tk->setLastActivity($this->time - 200); + $this->config->method('getSystemValueBool') + ->willReturnMap([ + ['auth.storeCryptedPassword', true, true], + ]); $this->tokenProvider->updateTokenActivity($tk); @@ -157,6 +212,10 @@ class PublicKeyTokenProviderTest extends TestCase { $password = 'passme'; $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'; $type = IToken::PERMANENT_TOKEN; + $this->config->method('getSystemValueBool') + ->willReturnMap([ + ['auth.storeCryptedPassword', true, true], + ]); $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER); @@ -185,6 +244,10 @@ class PublicKeyTokenProviderTest extends TestCase { $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'; $type = IToken::PERMANENT_TOKEN; + $this->config->method('getSystemValueBool') + ->willReturnMap([ + ['auth.storeCryptedPassword', true, true], + ]); $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER); $this->tokenProvider->getPassword($actual, 'wrongtoken'); @@ -197,6 +260,10 @@ class PublicKeyTokenProviderTest extends TestCase { $password = 'passme'; $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'; $type = IToken::PERMANENT_TOKEN; + $this->config->method('getSystemValueBool') + ->willReturnMap([ + ['auth.storeCryptedPassword', true, true], + ]); $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER); @@ -301,7 +368,7 @@ class PublicKeyTokenProviderTest extends TestCase { $this->tokenProvider->renewSessionToken('oldId', 'newId'); } - public function testRenewSessionTokenWithPassword() { + public function testRenewSessionTokenWithPassword(): void { $token = 'oldId'; $uid = 'user'; $user = 'User'; @@ -309,6 +376,10 @@ class PublicKeyTokenProviderTest extends TestCase { $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'; $type = IToken::PERMANENT_TOKEN; + $this->config->method('getSystemValueBool') + ->willReturnMap([ + ['auth.storeCryptedPassword', true, true], + ]); $oldToken = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER); $this->mapper @@ -319,7 +390,7 @@ class PublicKeyTokenProviderTest extends TestCase { $this->mapper ->expects($this->once()) ->method('insert') - ->with($this->callback(function (PublicKeyToken $token) use ($user, $uid, $name) { + ->with($this->callback(function (PublicKeyToken $token) use ($user, $uid, $name): bool { return $token->getUID() === $uid && $token->getLoginName() === $user && $token->getName() === $name && @@ -331,14 +402,14 @@ class PublicKeyTokenProviderTest extends TestCase { $this->mapper ->expects($this->once()) ->method('delete') - ->with($this->callback(function ($token) use ($oldToken) { + ->with($this->callback(function ($token) use ($oldToken): bool { return $token === $oldToken; })); $this->tokenProvider->renewSessionToken('oldId', 'newId'); } - public function testGetToken() { + public function testGetToken(): void { $token = new PublicKeyToken(); $this->config->method('getSystemValue') @@ -441,6 +512,10 @@ class PublicKeyTokenProviderTest extends TestCase { $name = 'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12'; $type = IToken::PERMANENT_TOKEN; + $this->config->method('getSystemValueBool') + ->willReturnMap([ + ['auth.storeCryptedPassword', true, true], + ]); $actual = $this->tokenProvider->generateToken($token, $uid, $user, $password, $name, $type, IToken::DO_NOT_REMEMBER); $new = $this->tokenProvider->rotate($actual, 'oldtoken', 'newtoken'); @@ -507,6 +582,10 @@ class PublicKeyTokenProviderTest extends TestCase { 'random2', IToken::PERMANENT_TOKEN, IToken::REMEMBER); + $this->config->method('getSystemValueBool') + ->willReturnMap([ + ['auth.storeCryptedPassword', true, true], + ]); $this->mapper->method('hasExpiredTokens') ->with($uid) diff --git a/tests/lib/Avatar/AvatarManagerTest.php b/tests/lib/Avatar/AvatarManagerTest.php index ce6981a2a21..06ff4086f72 100644 --- a/tests/lib/Avatar/AvatarManagerTest.php +++ b/tests/lib/Avatar/AvatarManagerTest.php @@ -37,6 +37,7 @@ use OCP\Files\SimpleFS\ISimpleFolder; use OCP\IConfig; use OCP\IL10N; use OCP\IUser; +use OC\User\User; use OCP\IUserSession; use Psr\Log\LoggerInterface; @@ -101,7 +102,7 @@ class AvatarManagerTest extends \Test\TestCase { } public function testGetAvatarForSelf() { - $user = $this->createMock(IUser::class); + $user = $this->createMock(User::class); $user ->expects($this->any()) ->method('getUID') @@ -151,7 +152,7 @@ class AvatarManagerTest extends \Test\TestCase { } public function testGetAvatarValidUserDifferentCasing() { - $user = $this->createMock(IUser::class); + $user = $this->createMock(User::class); $this->userManager->expects($this->once()) ->method('get') ->with('vaLid-USER') @@ -161,6 +162,10 @@ class AvatarManagerTest extends \Test\TestCase { ->method('getUID') ->willReturn('valid-user'); + $this->userSession->expects($this->once()) + ->method('getUser') + ->willReturn($user); + $folder = $this->createMock(ISimpleFolder::class); $this->appData ->expects($this->once()) @@ -168,26 +173,45 @@ class AvatarManagerTest extends \Test\TestCase { ->with('valid-user') ->willReturn($folder); + $account = $this->createMock(IAccount::class); + $this->accountManager->expects($this->once()) + ->method('getAccount') + ->with($user) + ->willReturn($account); + + $property = $this->createMock(IAccountProperty::class); + $account->expects($this->once()) + ->method('getProperty') + ->with(IAccountManager::PROPERTY_AVATAR) + ->willReturn($property); + + $property->expects($this->once()) + ->method('getScope') + ->willReturn(IAccountManager::SCOPE_FEDERATED); + $expected = new UserAvatar($folder, $this->l10n, $user, $this->logger, $this->config); $this->assertEquals($expected, $this->avatarManager->getAvatar('vaLid-USER')); } - public function knownUnknownProvider() { + public function dataGetAvatarScopes() { return [ - [IAccountManager::SCOPE_LOCAL, false, false, false], - [IAccountManager::SCOPE_LOCAL, true, false, false], - // public access cannot see real avatar [IAccountManager::SCOPE_PRIVATE, true, false, true], // unknown users cannot see real avatar [IAccountManager::SCOPE_PRIVATE, false, false, true], // known users can see real avatar [IAccountManager::SCOPE_PRIVATE, false, true, false], + [IAccountManager::SCOPE_LOCAL, false, false, false], + [IAccountManager::SCOPE_LOCAL, true, false, false], + [IAccountManager::SCOPE_FEDERATED, false, false, false], + [IAccountManager::SCOPE_FEDERATED, true, false, false], + [IAccountManager::SCOPE_PUBLISHED, false, false, false], + [IAccountManager::SCOPE_PUBLISHED, true, false, false], ]; } /** - * @dataProvider knownUnknownProvider + * @dataProvider dataGetAvatarScopes */ public function testGetAvatarScopes($avatarScope, $isPublicCall, $isKnownUser, $expectedPlaceholder) { if ($isPublicCall) { @@ -202,7 +226,7 @@ class AvatarManagerTest extends \Test\TestCase { ->method('getUser') ->willReturn($requestingUser); - $user = $this->createMock(IUser::class); + $user = $this->createMock(User::class); $user ->expects($this->once()) ->method('getUID') diff --git a/tests/lib/Avatar/UserAvatarTest.php b/tests/lib/Avatar/UserAvatarTest.php index dd5f25163f2..9a81f0bcd35 100644 --- a/tests/lib/Avatar/UserAvatarTest.php +++ b/tests/lib/Avatar/UserAvatarTest.php @@ -11,7 +11,6 @@ namespace Test\Avatar; use OC\Files\SimpleFS\SimpleFolder; use OC\User\User; use OCP\Files\File; -use OCP\Files\Folder; use OCP\Files\NotFoundException; use OCP\Files\SimpleFS\ISimpleFile; use OCP\IConfig; @@ -19,7 +18,7 @@ use OCP\IL10N; use Psr\Log\LoggerInterface; class UserAvatarTest extends \Test\TestCase { - /** @var Folder | \PHPUnit\Framework\MockObject\MockObject */ + /** @var SimpleFolder | \PHPUnit\Framework\MockObject\MockObject */ private $folder; /** @var \OC\Avatar\UserAvatar */ @@ -57,7 +56,7 @@ class UserAvatarTest extends \Test\TestCase { ->willReturn($file); $this->folder->method('getFile') - ->willReturnCallback(function ($path) { + ->willReturnCallback(function (string $path) { if ($path === 'avatar.64.png') { throw new NotFoundException(); } @@ -91,12 +90,13 @@ class UserAvatarTest extends \Test\TestCase { ->willReturnMap([ ['avatar.jpg', true], ['avatar.128.jpg', true], + ['generated', false], ]); $expected = new \OC_Image(); $expected->loadFromFile(\OC::$SERVERROOT . '/tests/data/testavatar.png'); - $file = $this->createMock(File::class); + $file = $this->createMock(ISimpleFile::class); $file->method('getContent')->willReturn($expected->data()); $this->folder->method('getFile')->with('avatar.128.jpg')->willReturn($file); @@ -107,12 +107,13 @@ class UserAvatarTest extends \Test\TestCase { $this->folder->method('fileExists') ->willReturnMap([ ['avatar.jpg', true], + ['generated', false], ]); $expected = new \OC_Image(); $expected->loadFromFile(\OC::$SERVERROOT . '/tests/data/testavatar.png'); - $file = $this->createMock(File::class); + $file = $this->createMock(ISimpleFile::class); $file->method('getContent')->willReturn($expected->data()); $this->folder->method('getFile')->with('avatar.jpg')->willReturn($file); @@ -122,8 +123,10 @@ class UserAvatarTest extends \Test\TestCase { public function testGetAvatarNoSizeMatch() { $this->folder->method('fileExists') ->willReturnMap([ + ['avatar.jpg', false], ['avatar.png', true], ['avatar.32.png', false], + ['generated', false], ]); $expected = new \OC_Image(); @@ -132,7 +135,7 @@ class UserAvatarTest extends \Test\TestCase { $expected2->loadFromFile(\OC::$SERVERROOT . '/tests/data/testavatar.png'); $expected2->resize(32); - $file = $this->createMock(File::class); + $file = $this->createMock(ISimpleFile::class); $file->method('getContent')->willReturn($expected->data()); $this->folder->method('getFile') @@ -146,7 +149,7 @@ class UserAvatarTest extends \Test\TestCase { } ); - $newFile = $this->createMock(File::class); + $newFile = $this->createMock(ISimpleFile::class); $newFile->expects($this->once()) ->method('putContent') ->with($expected2->data()); @@ -202,12 +205,12 @@ class UserAvatarTest extends \Test\TestCase { $this->folder->method('getDirectoryListing') ->willReturn([$avatarFileJPG, $avatarFilePNG, $resizedAvatarFile]); - $generated = $this->createMock(File::class); + $generated = $this->createMock(ISimpleFile::class); $this->folder->method('getFile') ->with('generated') ->willReturn($generated); - $newFile = $this->createMock(File::class); + $newFile = $this->createMock(ISimpleFile::class); $this->folder->expects($this->once()) ->method('newFile') ->with('avatar.png') @@ -258,17 +261,17 @@ class UserAvatarTest extends \Test\TestCase { } public function testMixPalette() { - $colorFrom = new \OC\Color(0, 0, 0); - $colorTo = new \OC\Color(6, 12, 18); + $colorFrom = new \OCP\Color(0, 0, 0); + $colorTo = new \OCP\Color(6, 12, 18); $steps = 6; - $palette = $this->invokePrivate($this->avatar, 'mixPalette', [$steps, $colorFrom, $colorTo]); + $palette = \OCP\Color::mixPalette($steps, $colorFrom, $colorTo); foreach ($palette as $j => $color) { // calc increment - $incR = $colorTo->r / $steps * $j; - $incG = $colorTo->g / $steps * $j; - $incB = $colorTo->b / $steps * $j; + $incR = $colorTo->red() / $steps * $j; + $incG = $colorTo->green() / $steps * $j; + $incB = $colorTo->blue() / $steps * $j; // ensure everything is equal - $this->assertEquals($color, new \OC\Color($incR, $incG, $incB)); + $this->assertEquals($color, new \OCP\Color($incR, $incG, $incB)); } $hashToInt = $this->invokePrivate($this->avatar, 'hashToInt', ['abcdef', 18]); $this->assertTrue(gettype($hashToInt) === 'integer'); diff --git a/tests/lib/BackgroundJob/DummyJobList.php b/tests/lib/BackgroundJob/DummyJobList.php index 0751409f62c..be9c06257b7 100644 --- a/tests/lib/BackgroundJob/DummyJobList.php +++ b/tests/lib/BackgroundJob/DummyJobList.php @@ -19,20 +19,20 @@ class DummyJobList extends \OC\BackgroundJob\JobList { /** * @var IJob[] */ - private $jobs = []; + private array $jobs = []; - private $last = 0; + private int $last = 0; public function __construct() { } /** - * @param IJob|string $job + * @param IJob|class-string<IJob> $job * @param mixed $argument */ - public function add($job, $argument = null) { + public function add($job, $argument = null): void { if (is_string($job)) { - /** @var \OC\BackgroundJob\Job $job */ + /** @var IJob $job */ $job = new $job; } $job->setArgument($argument); @@ -45,7 +45,7 @@ class DummyJobList extends \OC\BackgroundJob\JobList { * @param IJob|string $job * @param mixed $argument */ - public function remove($job, $argument = null) { + public function remove($job, $argument = null): void { $index = array_search($job, $this->jobs); if ($index !== false) { unset($this->jobs[$index]); @@ -59,7 +59,7 @@ class DummyJobList extends \OC\BackgroundJob\JobList { * @param mixed $argument * @return bool */ - public function has($job, $argument) { + public function has($job, $argument): bool { return array_search($job, $this->jobs) !== false; } @@ -68,15 +68,28 @@ class DummyJobList extends \OC\BackgroundJob\JobList { * * @return IJob[] */ - public function getAll() { + public function getAll(): array { return $this->jobs; } + public function getJobs($job, ?int $limit, int $offset): array { + if ($job instanceof IJob) { + $jobClass = get_class($job); + } else { + $jobClass = $job; + } + return array_slice( + array_filter( + $this->jobs, + fn ($job) => ($jobClass === null) || (get_class($job) == $jobClass) + ), + $offset, + $limit + ); + } + /** * get the next job in the list - * - * @param bool $onlyTimeSensitive - * @return IJob|null */ public function getNext(bool $onlyTimeSensitive = false): ?IJob { if (count($this->jobs) > 0) { @@ -96,7 +109,7 @@ class DummyJobList extends \OC\BackgroundJob\JobList { * * @param \OC\BackgroundJob\Job $job */ - public function setLastJob(IJob $job) { + public function setLastJob(IJob $job): void { $i = array_search($job, $this->jobs); if ($i !== false) { $this->last = $i; @@ -105,11 +118,7 @@ class DummyJobList extends \OC\BackgroundJob\JobList { } } - /** - * @param int $id - * @return IJob - */ - public function getById($id) { + public function getById(int $id): IJob { foreach ($this->jobs as $job) { if ($job->getId() === $id) { return $job; @@ -122,16 +131,11 @@ class DummyJobList extends \OC\BackgroundJob\JobList { return null; } - /** - * set the lastRun of $job to now - * - * @param IJob $job - */ - public function setLastRun(IJob $job) { + public function setLastRun(IJob $job): void { $job->setLastRun(time()); } - public function setExecutionTime(IJob $job, $timeTaken) { + public function setExecutionTime(IJob $job, $timeTaken): void { } public function resetBackgroundJob(IJob $job): void { diff --git a/tests/lib/Cache/CappedMemoryCacheTest.php b/tests/lib/Cache/CappedMemoryCacheTest.php index db0d2bd1193..b9d10b66100 100644 --- a/tests/lib/Cache/CappedMemoryCacheTest.php +++ b/tests/lib/Cache/CappedMemoryCacheTest.php @@ -30,11 +30,11 @@ namespace Test\Cache; class CappedMemoryCacheTest extends TestCache { protected function setUp(): void { parent::setUp(); - $this->instance = new \OC\Cache\CappedMemoryCache(); + $this->instance = new \OCP\Cache\CappedMemoryCache(); } public function testSetOverCap() { - $instance = new \OC\Cache\CappedMemoryCache(3); + $instance = new \OCP\Cache\CappedMemoryCache(3); $instance->set('1', 'a'); $instance->set('2', 'b'); diff --git a/tests/lib/Collaboration/Collaborators/LookupPluginTest.php b/tests/lib/Collaboration/Collaborators/LookupPluginTest.php index 1d856252745..b52e1d2745e 100644 --- a/tests/lib/Collaboration/Collaborators/LookupPluginTest.php +++ b/tests/lib/Collaboration/Collaborators/LookupPluginTest.php @@ -92,19 +92,20 @@ class LookupPluginTest extends TestCase { ->method('getAppValue') ->with('files_sharing', 'lookupServerEnabled', 'yes') ->willReturn('yes'); - $this->config->expects($this->at(0)) + $this->config->expects($this->exactly(2)) ->method('getSystemValue') - ->with('gs.enabled', false) - ->willReturn(false); + ->withConsecutive( + ['gs.enabled', false], + ['lookup_server', 'https://lookup.nextcloud.com'], + )->willReturnOnConsecutiveCalls( + false, + '', + ); - $this->config->expects($this->at(2)) + $this->config->expects($this->once()) ->method('getSystemValueBool') ->with('has_internet_connection', true) ->willReturn(true); - $this->config->expects($this->at(3)) - ->method('getSystemValue') - ->with('lookup_server', 'https://lookup.nextcloud.com') - ->willReturn(''); $this->clientService->expects($this->never()) ->method('newClient'); @@ -120,12 +121,12 @@ class LookupPluginTest extends TestCase { ->method('getAppValue') ->with('files_sharing', 'lookupServerEnabled', 'yes') ->willReturn('yes'); - $this->config->expects($this->at(0)) + $this->config->expects($this->once()) ->method('getSystemValue') ->with('gs.enabled', false) ->willReturn(false); - $this->config->expects($this->at(2)) + $this->config->expects($this->once()) ->method('getSystemValueBool') ->with('has_internet_connection', true) ->willReturn(false); @@ -156,19 +157,20 @@ class LookupPluginTest extends TestCase { ->method('getAppValue') ->with('files_sharing', 'lookupServerEnabled', 'yes') ->willReturn('yes'); - $this->config->expects($this->at(0)) + $this->config->expects($this->exactly(2)) ->method('getSystemValue') - ->with('gs.enabled', false) - ->willReturn(false); + ->withConsecutive( + ['gs.enabled', false], + ['lookup_server', 'https://lookup.nextcloud.com'], + )->willReturnOnConsecutiveCalls( + false, + $searchParams['server'], + ); - $this->config->expects($this->at(2)) + $this->config->expects($this->once()) ->method('getSystemValueBool') ->with('has_internet_connection', true) ->willReturn(true); - $this->config->expects($this->at(3)) - ->method('getSystemValue') - ->with('lookup_server', 'https://lookup.nextcloud.com') - ->willReturn($searchParams['server']); $response = $this->createMock(IResponse::class); $response->expects($this->once()) @@ -215,23 +217,24 @@ class LookupPluginTest extends TestCase { ->method('getAppValue') ->with('files_sharing', 'lookupServerEnabled', 'yes') ->willReturn($LookupEnabled ? 'yes' : 'no'); - $this->config->expects($this->at(0)) - ->method('getSystemValue') - ->with('gs.enabled', false) - ->willReturn($GSEnabled); if ($GSEnabled || $LookupEnabled) { $searchResult->expects($this->once()) ->method('addResultSet') ->with($type, $searchParams['expectedResult'], []); - $this->config->expects($this->at(2)) + $this->config->expects($this->once()) ->method('getSystemValueBool') ->with('has_internet_connection', true) ->willReturn(true); - $this->config->expects($this->at(3)) + $this->config->expects($this->exactly(2)) ->method('getSystemValue') - ->with('lookup_server', 'https://lookup.nextcloud.com') - ->willReturn($searchParams['server']); + ->withConsecutive( + ['gs.enabled', false], + ['lookup_server', 'https://lookup.nextcloud.com'], + )->willReturnOnConsecutiveCalls( + $GSEnabled, + $searchParams['server'], + ); $response = $this->createMock(IResponse::class); $response->expects($this->once()) @@ -252,6 +255,10 @@ class LookupPluginTest extends TestCase { ->willReturn($client); } else { $searchResult->expects($this->never())->method('addResultSet'); + $this->config->expects($this->once()) + ->method('getSystemValue') + ->with('gs.enabled', false) + ->willReturn($GSEnabled); } $moreResults = $this->plugin->search( $searchParams['search'], diff --git a/tests/lib/Collaboration/Collaborators/UserPluginTest.php b/tests/lib/Collaboration/Collaborators/UserPluginTest.php index 20e1ed898ad..0d9d89c7f8b 100644 --- a/tests/lib/Collaboration/Collaborators/UserPluginTest.php +++ b/tests/lib/Collaboration/Collaborators/UserPluginTest.php @@ -23,9 +23,6 @@ namespace Test\Collaboration\Collaborators; -use OC\Collaboration\Collaborators\SearchResult; -use OC\Collaboration\Collaborators\UserPlugin; -use OC\KnownUser\KnownUserService; use OCP\Collaboration\Collaborators\ISearchResult; use OCP\IConfig; use OCP\IGroup; @@ -35,25 +32,29 @@ use OCP\IUserManager; use OCP\IUserSession; use OCP\Share\IShare; use OCP\UserStatus\IManager as IUserStatusManager; +use OC\Collaboration\Collaborators\SearchResult; +use OC\Collaboration\Collaborators\UserPlugin; +use OC\KnownUser\KnownUserService; +use PHPUnit\Framework\MockObject\MockObject; use Test\TestCase; class UserPluginTest extends TestCase { - /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IConfig|MockObject */ protected $config; - /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IUserManager|MockObject */ protected $userManager; - /** @var IGroupManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IGroupManager|MockObject */ protected $groupManager; - /** @var IUserSession|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IUserSession|MockObject */ protected $session; - /** @var KnownUserService|\PHPUnit\Framework\MockObject\MockObject */ + /** @var KnownUserService|MockObject */ protected $knownUserService; - /** @var IUserStatusManager|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IUserStatusManager|MockObject */ protected $userStatusManager; /** @var UserPlugin */ @@ -62,13 +63,11 @@ class UserPluginTest extends TestCase { /** @var ISearchResult */ protected $searchResult; - /** @var int */ - protected $limit = 2; + protected int $limit = 2; - /** @var int */ - protected $offset = 0; + protected int $offset = 0; - /** @var IUser|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IUser|MockObject */ protected $user; protected function setUp(): void { @@ -657,7 +656,7 @@ class UserPluginTest extends TestCase { [ 'core' => [ 'shareapi_allow_share_dialog_user_enumeration' => 'no', - 'shareapi_restrict_user_enumeration_full_match_ignore_second_display_name' => 'yes', + 'shareapi_restrict_user_enumeration_full_match_ignore_second_dn' => 'yes', ], ] ], @@ -798,13 +797,15 @@ class UserPluginTest extends TestCase { $this->session->expects($this->any()) ->method('getUser') ->willReturn($this->getUserMock('test', 'foo')); - // current user - $this->groupManager->expects($this->at(0)) - ->method('getUserGroupIds') - ->willReturn($userGroups); $this->groupManager->expects($this->any()) ->method('getUserGroupIds') - ->willReturnCallback(function ($user) use ($matchingUsers) { + ->willReturnCallback(function ($user) use ($matchingUsers, $userGroups) { + static $firstCall = true; + if ($firstCall) { + $firstCall = false; + // current user + return $userGroups; + } $neededObject = array_filter( $matchingUsers, function ($e) use ($user) { diff --git a/tests/lib/Collaboration/Resources/ProviderManagerTest.php b/tests/lib/Collaboration/Resources/ProviderManagerTest.php index 01e45de9fdf..8f408418409 100644 --- a/tests/lib/Collaboration/Resources/ProviderManagerTest.php +++ b/tests/lib/Collaboration/Resources/ProviderManagerTest.php @@ -91,14 +91,15 @@ class ProviderManagerTest extends TestCase { } public function testGetResourceProvidersValidAndInvalidProvider(): void { - $this->serverContainer->expects($this->at(0)) + $this->serverContainer->expects($this->exactly(2)) ->method('query') - ->with($this->equalTo('InvalidResourceProvider')) - ->willThrowException(new QueryException('A meaningful error message')); - $this->serverContainer->expects($this->at(1)) - ->method('query') - ->with($this->equalTo(ResourceProvider::class)) - ->willReturn($this->createMock(ResourceProvider::class)); + ->withConsecutive( + [$this->equalTo('InvalidResourceProvider')], + [$this->equalTo(ResourceProvider::class)], + )->willReturnOnConsecutiveCalls( + $this->throwException(new QueryException('A meaningful error message')), + $this->createMock(ResourceProvider::class), + ); $this->logger->expects($this->once()) ->method('error'); diff --git a/tests/lib/Command/CronBusTest.php b/tests/lib/Command/CronBusTest.php index ea610a135d8..100de0a861c 100644 --- a/tests/lib/Command/CronBusTest.php +++ b/tests/lib/Command/CronBusTest.php @@ -47,4 +47,11 @@ class CronBusTest extends AsyncBusTest { $job->execute($this->jobList); } } + + public function testClosureFromPreviousVersion() { + $serializedClosure = 'C:32:"Opis\\Closure\\SerializableClosure":217:{a:5:{s:3:"use";a:0:{}s:8:"function";s:64:"function () {\\Test\\Command\\AsyncBusTest::$lastCommand = \'opis\';}";s:5:"scope";s:24:"Test\\Command\\CronBusTest";s:4:"this";N;s:4:"self";s:32:"0000000027dcfe2f00000000407fa805";}}'; + $this->jobList->add('OC\Command\ClosureJob', $serializedClosure); + $this->runJobs(); + $this->assertEquals('opis', AsyncBusTest::$lastCommand); + } } diff --git a/tests/lib/Command/Integrity/SignAppTest.php b/tests/lib/Command/Integrity/SignAppTest.php index fefed296a0c..66005ca06f5 100644 --- a/tests/lib/Command/Integrity/SignAppTest.php +++ b/tests/lib/Command/Integrity/SignAppTest.php @@ -56,25 +56,24 @@ class SignAppTest extends TestCase { $outputInterface = $this->createMock(OutputInterface::class); $inputInterface - ->expects($this->at(0)) + ->expects($this->exactly(3)) ->method('getOption') - ->with('path') - ->willReturn(null); - $inputInterface - ->expects($this->at(1)) - ->method('getOption') - ->with('privateKey') - ->willReturn('PrivateKey'); - $inputInterface - ->expects($this->at(2)) - ->method('getOption') - ->with('certificate') - ->willReturn('Certificate'); + ->withConsecutive( + ['path'], + ['privateKey'], + ['certificate'], + )->willReturnOnConsecutiveCalls( + null, + 'PrivateKey', + 'Certificate', + ); $outputInterface - ->expects($this->at(0)) + ->expects($this->any()) ->method('writeln') - ->with('This command requires the --path, --privateKey and --certificate.'); + ->withConsecutive( + ['This command requires the --path, --privateKey and --certificate.'] + ); $this->assertSame(1, self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface])); } @@ -84,25 +83,24 @@ class SignAppTest extends TestCase { $outputInterface = $this->createMock(OutputInterface::class); $inputInterface - ->expects($this->at(0)) + ->expects($this->exactly(3)) ->method('getOption') - ->with('path') - ->willReturn('AppId'); - $inputInterface - ->expects($this->at(1)) - ->method('getOption') - ->with('privateKey') - ->willReturn(null); - $inputInterface - ->expects($this->at(2)) - ->method('getOption') - ->with('certificate') - ->willReturn('Certificate'); + ->withConsecutive( + ['path'], + ['privateKey'], + ['certificate'], + )->willReturnOnConsecutiveCalls( + 'AppId', + null, + 'Certificate', + ); $outputInterface - ->expects($this->at(0)) - ->method('writeln') - ->with('This command requires the --path, --privateKey and --certificate.'); + ->expects($this->any()) + ->method('writeln') + ->withConsecutive( + ['This command requires the --path, --privateKey and --certificate.'] + ); $this->assertSame(1, self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface])); } @@ -112,25 +110,24 @@ class SignAppTest extends TestCase { $outputInterface = $this->createMock(OutputInterface::class); $inputInterface - ->expects($this->at(0)) + ->expects($this->exactly(3)) ->method('getOption') - ->with('path') - ->willReturn('AppId'); - $inputInterface - ->expects($this->at(1)) - ->method('getOption') - ->with('privateKey') - ->willReturn('privateKey'); - $inputInterface - ->expects($this->at(2)) - ->method('getOption') - ->with('certificate') - ->willReturn(null); + ->withConsecutive( + ['path'], + ['privateKey'], + ['certificate'], + )->willReturnOnConsecutiveCalls( + 'AppId', + 'privateKey', + null, + ); $outputInterface - ->expects($this->at(0)) + ->expects($this->any()) ->method('writeln') - ->with('This command requires the --path, --privateKey and --certificate.'); + ->withConsecutive( + ['This command requires the --path, --privateKey and --certificate.'] + ); $this->assertSame(1, self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface])); } @@ -140,31 +137,31 @@ class SignAppTest extends TestCase { $outputInterface = $this->createMock(OutputInterface::class); $inputInterface - ->expects($this->at(0)) + ->expects($this->exactly(3)) ->method('getOption') - ->with('path') - ->willReturn('AppId'); - $inputInterface - ->expects($this->at(1)) - ->method('getOption') - ->with('privateKey') - ->willReturn('privateKey'); - $inputInterface - ->expects($this->at(2)) - ->method('getOption') - ->with('certificate') - ->willReturn('certificate'); + ->withConsecutive( + ['path'], + ['privateKey'], + ['certificate'], + )->willReturnOnConsecutiveCalls( + 'AppId', + 'privateKey', + 'certificate', + ); $this->fileAccessHelper - ->expects($this->at(0)) + ->expects($this->any()) ->method('file_get_contents') - ->with('privateKey') - ->willReturn(false); + ->withConsecutive(['privateKey']) + ->willReturnOnConsecutiveCalls(false); + $outputInterface - ->expects($this->at(0)) + ->expects($this->any()) ->method('writeln') - ->with('Private key "privateKey" does not exists.'); + ->withConsecutive( + ['Private key "privateKey" does not exists.'] + ); $this->assertSame(1, self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface])); } @@ -174,36 +171,36 @@ class SignAppTest extends TestCase { $outputInterface = $this->createMock(OutputInterface::class); $inputInterface - ->expects($this->at(0)) + ->expects($this->exactly(3)) ->method('getOption') - ->with('path') - ->willReturn('AppId'); - $inputInterface - ->expects($this->at(1)) - ->method('getOption') - ->with('privateKey') - ->willReturn('privateKey'); - $inputInterface - ->expects($this->at(2)) - ->method('getOption') - ->with('certificate') - ->willReturn('certificate'); + ->withConsecutive( + ['path'], + ['privateKey'], + ['certificate'], + )->willReturnOnConsecutiveCalls( + 'AppId', + 'privateKey', + 'certificate', + ); $this->fileAccessHelper - ->expects($this->at(0)) + ->expects($this->any()) ->method('file_get_contents') - ->with('privateKey') - ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key'); - $this->fileAccessHelper - ->expects($this->at(1)) - ->method('file_get_contents') - ->with('certificate') - ->willReturn(false); + ->withConsecutive( + ['privateKey'], + ['certificate'], + ) + ->willReturnOnConsecutiveCalls( + \OC::$SERVERROOT . '/tests/data/integritycheck/core.key', + false + ); $outputInterface - ->expects($this->at(0)) + ->expects($this->any()) ->method('writeln') - ->with('Certificate "certificate" does not exists.'); + ->withConsecutive( + ['Certificate "certificate" does not exists.'] + ); $this->assertSame(1, self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface])); } @@ -213,31 +210,29 @@ class SignAppTest extends TestCase { $outputInterface = $this->createMock(OutputInterface::class); $inputInterface - ->expects($this->at(0)) - ->method('getOption') - ->with('path') - ->willReturn('AppId'); - $inputInterface - ->expects($this->at(1)) - ->method('getOption') - ->with('privateKey') - ->willReturn('privateKey'); - $inputInterface - ->expects($this->at(2)) + ->expects($this->exactly(3)) ->method('getOption') - ->with('certificate') - ->willReturn('certificate'); + ->withConsecutive( + ['path'], + ['privateKey'], + ['certificate'], + )->willReturnOnConsecutiveCalls( + 'AppId', + 'privateKey', + 'certificate', + ); $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with('privateKey') - ->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')); - $this->fileAccessHelper - ->expects($this->at(1)) + ->expects($this->any()) ->method('file_get_contents') - ->with('certificate') - ->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt')); + ->withConsecutive( + ['privateKey'], + ['certificate'], + ) + ->willReturnOnConsecutiveCalls( + file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key'), + file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt'), + ); $this->checker ->expects($this->once()) @@ -245,9 +240,11 @@ class SignAppTest extends TestCase { ->willThrowException(new \Exception('My error message')); $outputInterface - ->expects($this->at(0)) + ->expects($this->any()) ->method('writeln') - ->with('Error: My error message'); + ->withConsecutive( + ['Error: My error message'] + ); $this->assertSame(1, self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface])); } @@ -257,40 +254,40 @@ class SignAppTest extends TestCase { $outputInterface = $this->createMock(OutputInterface::class); $inputInterface - ->expects($this->at(0)) - ->method('getOption') - ->with('path') - ->willReturn('AppId'); - $inputInterface - ->expects($this->at(1)) + ->expects($this->exactly(3)) ->method('getOption') - ->with('privateKey') - ->willReturn('privateKey'); - $inputInterface - ->expects($this->at(2)) - ->method('getOption') - ->with('certificate') - ->willReturn('certificate'); + ->withConsecutive( + ['path'], + ['privateKey'], + ['certificate'], + )->willReturnOnConsecutiveCalls( + 'AppId', + 'privateKey', + 'certificate', + ); $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with('privateKey') - ->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')); - $this->fileAccessHelper - ->expects($this->at(1)) + ->expects($this->any()) ->method('file_get_contents') - ->with('certificate') - ->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt')); + ->withConsecutive( + ['privateKey'], + ['certificate'], + ) + ->willReturnOnConsecutiveCalls( + file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key'), + file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt'), + ); $this->checker ->expects($this->once()) ->method('writeAppSignature'); $outputInterface - ->expects($this->at(0)) + ->expects($this->any()) ->method('writeln') - ->with('Successfully signed "AppId"'); + ->withConsecutive( + ['Successfully signed "AppId"'] + ); $this->assertSame(0, self::invokePrivate($this->signApp, 'execute', [$inputInterface, $outputInterface])); } diff --git a/tests/lib/Command/Integrity/SignCoreTest.php b/tests/lib/Command/Integrity/SignCoreTest.php index 3b7fe7f3a8b..d67e2a9e2b4 100644 --- a/tests/lib/Command/Integrity/SignCoreTest.php +++ b/tests/lib/Command/Integrity/SignCoreTest.php @@ -51,20 +51,24 @@ class SignCoreTest extends TestCase { $outputInterface = $this->createMock(OutputInterface::class); $inputInterface - ->expects($this->at(0)) + ->expects($this->exactly(3)) ->method('getOption') - ->with('privateKey') - ->willReturn(null); - $inputInterface - ->expects($this->at(1)) - ->method('getOption') - ->with('certificate') - ->willReturn('Certificate'); + ->withConsecutive( + ['privateKey'], + ['certificate'], + ['path'], + )->willReturnOnConsecutiveCalls( + null, + 'certificate', + 'certificate', + ); $outputInterface - ->expects($this->at(0)) + ->expects($this->any()) ->method('writeln') - ->with('--privateKey, --certificate and --path are required.'); + ->withConsecutive( + ['--privateKey, --certificate and --path are required.'] + ); $this->assertSame(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface])); } @@ -74,20 +78,24 @@ class SignCoreTest extends TestCase { $outputInterface = $this->createMock(OutputInterface::class); $inputInterface - ->expects($this->at(0)) - ->method('getOption') - ->with('privateKey') - ->willReturn('privateKey'); - $inputInterface - ->expects($this->at(1)) + ->expects($this->exactly(3)) ->method('getOption') - ->with('certificate') - ->willReturn(null); + ->withConsecutive( + ['privateKey'], + ['certificate'], + ['path'], + )->willReturnOnConsecutiveCalls( + 'privateKey', + null, + 'certificate', + ); $outputInterface - ->expects($this->at(0)) + ->expects($this->any()) ->method('writeln') - ->with('--privateKey, --certificate and --path are required.'); + ->withConsecutive( + ['--privateKey, --certificate and --path are required.'] + ); $this->assertSame(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface])); } @@ -97,31 +105,34 @@ class SignCoreTest extends TestCase { $outputInterface = $this->createMock(OutputInterface::class); $inputInterface - ->expects($this->at(0)) - ->method('getOption') - ->with('privateKey') - ->willReturn('privateKey'); - $inputInterface - ->expects($this->at(1)) + ->expects($this->exactly(3)) ->method('getOption') - ->with('certificate') - ->willReturn('certificate'); - $inputInterface - ->expects($this->at(2)) - ->method('getOption') - ->with('path') - ->willReturn('certificate'); + ->withConsecutive( + ['privateKey'], + ['certificate'], + ['path'], + )->willReturnOnConsecutiveCalls( + 'privateKey', + 'certificate', + 'certificate', + ); $this->fileAccessHelper - ->expects($this->at(0)) + ->expects($this->any()) ->method('file_get_contents') - ->with('privateKey') - ->willReturn(false); + ->withConsecutive( + ['privateKey'], + ) + ->willReturnOnConsecutiveCalls( + false, + ); $outputInterface - ->expects($this->at(0)) + ->expects($this->any()) ->method('writeln') - ->with('Private key "privateKey" does not exists.'); + ->withConsecutive( + ['Private key "privateKey" does not exists.'] + ); $this->assertSame(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface])); } @@ -131,36 +142,36 @@ class SignCoreTest extends TestCase { $outputInterface = $this->createMock(OutputInterface::class); $inputInterface - ->expects($this->at(0)) - ->method('getOption') - ->with('privateKey') - ->willReturn('privateKey'); - $inputInterface - ->expects($this->at(1)) + ->expects($this->exactly(3)) ->method('getOption') - ->with('certificate') - ->willReturn('certificate'); - $inputInterface - ->expects($this->at(2)) - ->method('getOption') - ->with('path') - ->willReturn('certificate'); + ->withConsecutive( + ['privateKey'], + ['certificate'], + ['path'], + )->willReturnOnConsecutiveCalls( + 'privateKey', + 'certificate', + 'certificate', + ); $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with('privateKey') - ->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')); - $this->fileAccessHelper - ->expects($this->at(1)) + ->expects($this->any()) ->method('file_get_contents') - ->with('certificate') - ->willReturn(false); + ->withConsecutive( + ['privateKey'], + ['certificate'], + ) + ->willReturnOnConsecutiveCalls( + file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key'), + false, + ); $outputInterface - ->expects($this->at(0)) + ->expects($this->any()) ->method('writeln') - ->with('Certificate "certificate" does not exists.'); + ->withConsecutive( + ['Certificate "certificate" does not exists.'] + ); $this->assertSame(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface])); } @@ -170,31 +181,29 @@ class SignCoreTest extends TestCase { $outputInterface = $this->createMock(OutputInterface::class); $inputInterface - ->expects($this->at(0)) + ->expects($this->exactly(3)) ->method('getOption') - ->with('privateKey') - ->willReturn('privateKey'); - $inputInterface - ->expects($this->at(1)) - ->method('getOption') - ->with('certificate') - ->willReturn('certificate'); - $inputInterface - ->expects($this->at(2)) - ->method('getOption') - ->with('path') - ->willReturn('certificate'); + ->withConsecutive( + ['privateKey'], + ['certificate'], + ['path'], + )->willReturnOnConsecutiveCalls( + 'privateKey', + 'certificate', + 'certificate', + ); $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with('privateKey') - ->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')); - $this->fileAccessHelper - ->expects($this->at(1)) + ->expects($this->any()) ->method('file_get_contents') - ->with('certificate') - ->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt')); + ->withConsecutive( + ['privateKey'], + ['certificate'], + ) + ->willReturnOnConsecutiveCalls( + file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key'), + file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt'), + ); $this->checker ->expects($this->once()) @@ -202,9 +211,11 @@ class SignCoreTest extends TestCase { ->willThrowException(new \Exception('My exception message')); $outputInterface - ->expects($this->at(0)) + ->expects($this->any()) ->method('writeln') - ->with('Error: My exception message'); + ->withConsecutive( + ['Error: My exception message'] + ); $this->assertEquals(1, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface])); } @@ -214,40 +225,40 @@ class SignCoreTest extends TestCase { $outputInterface = $this->createMock(OutputInterface::class); $inputInterface - ->expects($this->at(0)) + ->expects($this->exactly(3)) ->method('getOption') - ->with('privateKey') - ->willReturn('privateKey'); - $inputInterface - ->expects($this->at(1)) - ->method('getOption') - ->with('certificate') - ->willReturn('certificate'); - $inputInterface - ->expects($this->at(2)) - ->method('getOption') - ->with('path') - ->willReturn('certificate'); + ->withConsecutive( + ['privateKey'], + ['certificate'], + ['path'], + )->willReturnOnConsecutiveCalls( + 'privateKey', + 'certificate', + 'certificate', + ); $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with('privateKey') - ->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key')); - $this->fileAccessHelper - ->expects($this->at(1)) + ->expects($this->any()) ->method('file_get_contents') - ->with('certificate') - ->willReturn(file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt')); + ->withConsecutive( + ['privateKey'], + ['certificate'], + ) + ->willReturnOnConsecutiveCalls( + file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.key'), + file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/core.crt'), + ); $this->checker ->expects($this->once()) ->method('writeCoreSignature'); $outputInterface - ->expects($this->at(0)) + ->expects($this->any()) ->method('writeln') - ->with('Successfully signed "core"'); + ->withConsecutive( + ['Successfully signed "core"'] + ); $this->assertEquals(0, self::invokePrivate($this->signCore, 'execute', [$inputInterface, $outputInterface])); } diff --git a/tests/lib/Comments/FakeManager.php b/tests/lib/Comments/FakeManager.php index 5406df96a96..b524f5a5000 100644 --- a/tests/lib/Comments/FakeManager.php +++ b/tests/lib/Comments/FakeManager.php @@ -141,4 +141,8 @@ class FakeManager implements ICommentsManager { public function getLastCommentDateByActor(string $objectType, string $objectId, string $verb, string $actorType, array $actors): array { return []; } + + public function deleteCommentsExpiredAtObject(string $objectType, string $objectId = ''): bool { + return true; + } } diff --git a/tests/lib/Comments/ManagerTest.php b/tests/lib/Comments/ManagerTest.php index 6bcd0dec8ed..1af460e6f1b 100644 --- a/tests/lib/Comments/ManagerTest.php +++ b/tests/lib/Comments/ManagerTest.php @@ -14,6 +14,7 @@ use OCP\IConfig; use OCP\IDBConnection; use OCP\IInitialStateService; use OCP\IUser; +use OCP\Server; use Psr\Log\LoggerInterface; use Test\TestCase; @@ -37,7 +38,7 @@ class ManagerTest extends TestCase { $this->connection->prepare($sql)->execute(); } - protected function addDatabaseEntry($parentId, $topmostParentId, $creationDT = null, $latestChildDT = null, $objectId = null) { + protected function addDatabaseEntry($parentId, $topmostParentId, $creationDT = null, $latestChildDT = null, $objectId = null, $expireDate = null) { if (is_null($creationDT)) { $creationDT = new \DateTime(); } @@ -63,6 +64,7 @@ class ManagerTest extends TestCase { 'latest_child_timestamp' => $qb->createNamedParameter($latestChildDT, 'datetime'), 'object_type' => $qb->createNamedParameter('files'), 'object_id' => $qb->createNamedParameter($objectId), + 'expire_date' => $qb->createNamedParameter($expireDate, 'datetime'), ]) ->execute(); @@ -701,6 +703,91 @@ class ManagerTest extends TestCase { $this->assertTrue($wasSuccessful); } + public function testDeleteCommentsExpiredAtObjectTypeAndId(): void { + $ids = []; + $ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('+2 hours')); + $ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('+2 hours')); + $ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('+2 hours')); + $ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('-2 hours')); + $ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('-2 hours')); + $ids[] = $this->addDatabaseEntry(0, 0, null, null, null, new \DateTime('-2 hours')); + + $manager = new Manager( + $this->connection, + $this->createMock(LoggerInterface::class), + $this->createMock(IConfig::class), + Server::get(ITimeFactory::class), + new EmojiHelper($this->connection), + $this->createMock(IInitialStateService::class) + ); + + // just to make sure they are really set, with correct actor data + $comment = $manager->get((string) $ids[1]); + $this->assertSame($comment->getObjectType(), 'files'); + $this->assertSame($comment->getObjectId(), 'file64'); + + $deleted = $manager->deleteCommentsExpiredAtObject('files', 'file64'); + $this->assertTrue($deleted); + + $deleted = 0; + $exists = 0; + foreach ($ids as $id) { + try { + $manager->get((string) $id); + $exists++; + } catch (NotFoundException $e) { + $deleted++; + } + } + $this->assertSame($exists, 3); + $this->assertSame($deleted, 3); + + // actor info is gone from DB, but when database interaction is alright, + // we still expect to get true back + $deleted = $manager->deleteCommentsExpiredAtObject('files', 'file64'); + $this->assertFalse($deleted); + } + + public function testDeleteCommentsExpiredAtObjectType(): void { + $ids = []; + $ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file1', new \DateTime('-2 hours')); + $ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file2', new \DateTime('-2 hours')); + $ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file3', new \DateTime('-2 hours')); + $ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file3', new \DateTime()); + $ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file3', new \DateTime()); + $ids[] = $this->addDatabaseEntry(0, 0, null, null, 'file3', new \DateTime()); + + $manager = new Manager( + $this->connection, + $this->createMock(LoggerInterface::class), + $this->createMock(IConfig::class), + Server::get(ITimeFactory::class), + new EmojiHelper($this->connection), + $this->createMock(IInitialStateService::class) + ); + + $deleted = $manager->deleteCommentsExpiredAtObject('files'); + $this->assertTrue($deleted); + + $deleted = 0; + $exists = 0; + foreach ($ids as $id) { + try { + $manager->get((string) $id); + $exists++; + } catch (NotFoundException $e) { + $deleted++; + } + } + $this->assertSame($exists, 0); + $this->assertSame($deleted, 6); + + // actor info is gone from DB, but when database interaction is alright, + // we still expect to get true back + $deleted = $manager->deleteCommentsExpiredAtObject('files'); + $this->assertFalse($deleted); + } + public function testSetMarkRead() { /** @var IUser|\PHPUnit\Framework\MockObject\MockObject $user */ $user = $this->createMock(IUser::class); diff --git a/tests/lib/DB/MigrationsTest.php b/tests/lib/DB/MigrationsTest.php index 206fe1a3798..3d115f25adf 100644 --- a/tests/lib/DB/MigrationsTest.php +++ b/tests/lib/DB/MigrationsTest.php @@ -115,12 +115,12 @@ class MigrationsTest extends \Test\TestCase { ->willReturn($wrappedSchema); $step = $this->createMock(IMigrationStep::class); - $step->expects($this->at(0)) + $step->expects($this->once()) ->method('preSchemaChange'); - $step->expects($this->at(1)) + $step->expects($this->once()) ->method('changeSchema') ->willReturn($schemaResult); - $step->expects($this->at(2)) + $step->expects($this->once()) ->method('postSchemaChange'); $this->migrationService = $this->getMockBuilder(MigrationService::class) @@ -145,12 +145,12 @@ class MigrationsTest extends \Test\TestCase { ->method('migrateToSchema'); $step = $this->createMock(IMigrationStep::class); - $step->expects($this->at(0)) + $step->expects($this->once()) ->method('preSchemaChange'); - $step->expects($this->at(1)) + $step->expects($this->once()) ->method('changeSchema') ->willReturn(null); - $step->expects($this->at(2)) + $step->expects($this->once()) ->method('postSchemaChange'); $this->migrationService = $this->getMockBuilder(MigrationService::class) diff --git a/tests/lib/DB/QueryBuilder/FunctionBuilderTest.php b/tests/lib/DB/QueryBuilder/FunctionBuilderTest.php index 08392b09d8d..0ea6e69c956 100644 --- a/tests/lib/DB/QueryBuilder/FunctionBuilderTest.php +++ b/tests/lib/DB/QueryBuilder/FunctionBuilderTest.php @@ -501,4 +501,21 @@ class FunctionBuilderTest extends TestCase { $result->closeCursor(); $this->assertEquals(1, $row); } + + public function testCase() { + $query = $this->connection->getQueryBuilder(); + + $query->select($query->func()->case([ + ['when' => $query->expr()->gt($query->expr()->literal(1, IQueryBuilder::PARAM_INT), $query->expr()->literal(2, IQueryBuilder::PARAM_INT)), 'then' => $query->expr()->literal('first')], + ['when' => $query->expr()->lt($query->expr()->literal(1, IQueryBuilder::PARAM_INT), $query->expr()->literal(2, IQueryBuilder::PARAM_INT)), 'then' => $query->expr()->literal('second')], + ['when' => $query->expr()->eq($query->expr()->literal(1, IQueryBuilder::PARAM_INT), $query->expr()->literal(2, IQueryBuilder::PARAM_INT)), 'then' => $query->expr()->literal('third')], + ], $query->createNamedParameter('else'))); + $query->from('appconfig') + ->setMaxResults(1); + + $result = $query->execute(); + $row = $result->fetchOne(); + $result->closeCursor(); + $this->assertEquals('second', $row); + } } diff --git a/tests/lib/DirectEditing/ManagerTest.php b/tests/lib/DirectEditing/ManagerTest.php index b00de02bcf5..e19c44b1a06 100644 --- a/tests/lib/DirectEditing/ManagerTest.php +++ b/tests/lib/DirectEditing/ManagerTest.php @@ -106,6 +106,10 @@ class ManagerTest extends TestCase { */ private $userFolder; /** + * @var MockObject|IL10N + */ + private $l10n; + /** * @var MockObject|IManager */ private $encryptionManager; diff --git a/tests/lib/Encryption/DecryptAllTest.php b/tests/lib/Encryption/DecryptAllTest.php index 90ff045a9b9..92ed2dcd701 100644 --- a/tests/lib/Encryption/DecryptAllTest.php +++ b/tests/lib/Encryption/DecryptAllTest.php @@ -224,12 +224,12 @@ class DecryptAllTest extends TestCase { $this->userInterface->expects($this->any()) ->method('getUsers') ->willReturn(['user1', 'user2']); - $instance->expects($this->at(0)) + $instance->expects($this->exactly(2)) ->method('decryptUsersFiles') - ->with('user1'); - $instance->expects($this->at(1)) - ->method('decryptUsersFiles') - ->with('user2'); + ->withConsecutive( + ['user1'], + ['user2'], + ); } else { $instance->expects($this->once()) ->method('decryptUsersFiles') @@ -269,17 +269,18 @@ class DecryptAllTest extends TestCase { $sharedStorage->expects($this->once())->method('instanceOfStorage') ->with('OCA\Files_Sharing\SharedStorage')->willReturn(true); - $this->view->expects($this->at(0))->method('getDirectoryContent') - ->with('/user1/files')->willReturn( + $this->view->expects($this->exactly(2)) + ->method('getDirectoryContent') + ->withConsecutive( + ['/user1/files'], + ['/user1/files/foo'] + ) + ->willReturnOnConsecutiveCalls( [ new FileInfo('path', $storage, 'intPath', ['name' => 'foo', 'type' => 'dir'], null), new FileInfo('path', $storage, 'intPath', ['name' => 'bar', 'type' => 'file', 'encrypted' => true], null), new FileInfo('path', $sharedStorage, 'intPath', ['name' => 'shared', 'type' => 'file', 'encrypted' => true], null), - ] - ); - - $this->view->expects($this->at(3))->method('getDirectoryContent') - ->with('/user1/files/foo')->willReturn( + ], [ new FileInfo('path', $storage, 'intPath', ['name' => 'subfile', 'type' => 'file', 'encrypted' => true], null) ] @@ -295,12 +296,12 @@ class DecryptAllTest extends TestCase { } ); - $instance->expects($this->at(0)) - ->method('decryptFile') - ->with('/user1/files/bar'); - $instance->expects($this->at(1)) + $instance->expects($this->exactly(2)) ->method('decryptFile') - ->with('/user1/files/foo/subfile'); + ->withConsecutive( + ['/user1/files/bar'], + ['/user1/files/foo/subfile'], + ); /* We need format method to return a string */ diff --git a/tests/lib/Encryption/Keys/StorageTest.php b/tests/lib/Encryption/Keys/StorageTest.php index 30680646f73..bb7bbbcd7c1 100644 --- a/tests/lib/Encryption/Keys/StorageTest.php +++ b/tests/lib/Encryption/Keys/StorageTest.php @@ -162,21 +162,21 @@ class StorageTest extends TestCase { ->method('isSystemWideMountPoint') ->willReturn(false); - $this->view->expects($this->at(0)) - ->method('file_exists') - ->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey')) - ->willReturn($originalKeyExists); - $this->crypto->method('decrypt') ->willReturnCallback(function ($data, $pass) { return $data; }); if (!$originalKeyExists) { - $this->view->expects($this->at(1)) + $this->view->expects($this->exactly(2)) ->method('file_exists') - ->with($this->equalTo('/user1/files_encryption/keys' . $path . '/encModule/fileKey')) - ->willReturn(true); + ->withConsecutive( + [$this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey')], + [$this->equalTo('/user1/files_encryption/keys' . $path . '/encModule/fileKey')], + )->willReturnOnConsecutiveCalls( + $originalKeyExists, + true, + ); $this->view->expects($this->once()) ->method('file_get_contents') @@ -184,6 +184,11 @@ class StorageTest extends TestCase { ->willReturn(json_encode(['key' => base64_encode('key2')])); } else { $this->view->expects($this->once()) + ->method('file_exists') + ->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey')) + ->willReturn($originalKeyExists); + + $this->view->expects($this->once()) ->method('file_get_contents') ->with($this->equalTo('/user1/files_encryption/keys' . $strippedPartialName . '/encModule/fileKey')) ->willReturn(json_encode(['key' => base64_encode('key')])); @@ -627,10 +632,11 @@ class StorageTest extends TestCase { ->with('user1/files_encryption/backup')->willReturn(!$createBackupDir); if ($createBackupDir) { - $this->view->expects($this->at(1))->method('mkdir') - ->with('user1/files_encryption/backup'); - $this->view->expects($this->at(2))->method('mkdir') - ->with('user1/files_encryption/backup/test.encryptionModule.1234567'); + $this->view->expects($this->exactly(2))->method('mkdir') + ->withConsecutive( + ['user1/files_encryption/backup'], + ['user1/files_encryption/backup/test.encryptionModule.1234567'], + ); } else { $this->view->expects($this->once())->method('mkdir') ->with('user1/files_encryption/backup/test.encryptionModule.1234567'); diff --git a/tests/lib/Encryption/UtilTest.php b/tests/lib/Encryption/UtilTest.php index 84d81dd1cbb..248377fc698 100644 --- a/tests/lib/Encryption/UtilTest.php +++ b/tests/lib/Encryption/UtilTest.php @@ -4,8 +4,12 @@ namespace Test\Encryption; use OC\Encryption\Util; use OC\Files\View; +use OCA\Files_External\Lib\StorageConfig; +use OCA\Files_External\Service\GlobalStoragesService; use OCP\Encryption\IEncryptionModule; use OCP\IConfig; +use OCP\IGroupManager; +use OCP\IUserManager; use Test\TestCase; class UtilTest extends TestCase { @@ -13,24 +17,21 @@ class UtilTest extends TestCase { /** * block size will always be 8192 for a PHP stream * @see https://bugs.php.net/bug.php?id=21641 - * @var integer */ - protected $headerSize = 8192; + protected int $headerSize = 8192; /** @var \PHPUnit\Framework\MockObject\MockObject */ protected $view; - /** @var \PHPUnit\Framework\MockObject\MockObject */ + /** @var \PHPUnit\Framework\MockObject\MockObject|IUserManager */ protected $userManager; - /** @var \PHPUnit\Framework\MockObject\MockObject */ + /** @var \PHPUnit\Framework\MockObject\MockObject|IGroupManager */ protected $groupManager; - /** @var \PHPUnit\Framework\MockObject\MockObject */ + /** @var \PHPUnit\Framework\MockObject\MockObject|IConfig */ private $config; - - /** @var \OC\Encryption\Util */ - private $util; + private Util $util; protected function setUp(): void { parent::setUp(); @@ -38,17 +39,9 @@ class UtilTest extends TestCase { ->disableOriginalConstructor() ->getMock(); - $this->userManager = $this->getMockBuilder('OC\User\Manager') - ->disableOriginalConstructor() - ->getMock(); - - $this->groupManager = $this->getMockBuilder('OC\Group\Manager') - ->disableOriginalConstructor() - ->getMock(); - - $this->config = $this->getMockBuilder(IConfig::class) - ->disableOriginalConstructor() - ->getMock(); + $this->userManager = $this->createMock(IUserManager::class); + $this->groupManager = $this->createMock(IGroupManager::class); + $this->config = $this->createMock(IConfig::class); $this->util = new Util( $this->view, @@ -188,4 +181,43 @@ class UtilTest extends TestCase { ['/foo/test.txt.ocTransferId7567.part', '/foo/test.txt'], ]; } + + public function dataTestIsSystemWideMountPoint() { + return [ + [false, 'non-matching mount point name', [], [], '/mp_another'], + [true, 'applicable to all', [], []], + [true, 'applicable to user directly', ['user1'], []], + [true, 'applicable to group directly', [], ['group1']], + [false, 'non-applicable to current user', ['user2'], []], + [false, 'non-applicable to current user\'s group', [], ['group2']], + [true, 'mount point without leading slash', [], [], 'mp'], + ]; + } + + /** + * @dataProvider dataTestIsSystemWideMountPoint + */ + public function testIsSystemWideMountPoint($expectedResult, $expectationText, $applicableUsers, $applicableGroups, $mountPointName = '/mp') { + $this->groupManager->method('isInGroup') + ->will($this->returnValueMap([ + ['user1', 'group1', true], // user is only in group1 + ['user1', 'group2', false], + ])); + + $storages = []; + + $storageConfig = $this->createMock(StorageConfig::class); + $storageConfig->method('getMountPoint')->willReturn($mountPointName); + $storageConfig->method('getApplicableUsers')->willReturn($applicableUsers); + $storageConfig->method('getApplicableGroups')->willReturn($applicableGroups); + $storages[] = $storageConfig; + + $storagesServiceMock = $this->createMock(GlobalStoragesService::class); + $storagesServiceMock->expects($this->atLeastOnce())->method('getAllStorages') + ->willReturn($storages); + + $this->overwriteService(GlobalStoragesService::class, $storagesServiceMock); + + $this->assertEquals($expectedResult, $this->util->isSystemWideMountPoint('/files/mp', 'user1'), 'Test case: ' . $expectationText); + } } diff --git a/tests/lib/Files/Cache/SearchBuilderTest.php b/tests/lib/Files/Cache/SearchBuilderTest.php index 82c4dbaa27f..5eb1a0252f0 100644 --- a/tests/lib/Files/Cache/SearchBuilderTest.php +++ b/tests/lib/Files/Cache/SearchBuilderTest.php @@ -79,7 +79,7 @@ class SearchBuilderTest extends TestCase { $this->numericStorageId = 10000; $this->builder->select(['fileid']) - ->from('filecache') + ->from('filecache', 'file') // alias needed for QuerySearchHelper#getOperatorFieldAndValue ->where($this->builder->expr()->eq('storage', new Literal($this->numericStorageId))); } diff --git a/tests/lib/Files/Config/UserMountCacheTest.php b/tests/lib/Files/Config/UserMountCacheTest.php index 221159bc983..8b26b309daa 100644 --- a/tests/lib/Files/Config/UserMountCacheTest.php +++ b/tests/lib/Files/Config/UserMountCacheTest.php @@ -11,7 +11,7 @@ namespace Test\Files\Config; use OC\DB\QueryBuilder\Literal; use OC\Files\Mount\MountPoint; use OC\Files\Storage\Storage; -use OC\Cache\CappedMemoryCache; +use OCP\Cache\CappedMemoryCache; use OC\User\Manager; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\Config\ICachedMountInfo; diff --git a/tests/lib/Files/Mount/ObjectHomeMountProviderTest.php b/tests/lib/Files/Mount/ObjectHomeMountProviderTest.php index 5dc93660d9c..7ce87140122 100644 --- a/tests/lib/Files/Mount/ObjectHomeMountProviderTest.php +++ b/tests/lib/Files/Mount/ObjectHomeMountProviderTest.php @@ -201,17 +201,17 @@ class ObjectHomeMountProviderTest extends \Test\TestCase { } public function testMultiBucketConfigFirstFallBackSingle() { - $this->config->expects($this->at(0)) - ->method('getSystemValue') - ->with($this->equalTo('objectstore_multibucket')) - ->willReturn(''); - - $this->config->expects($this->at(1)) + $this->config->expects($this->exactly(2)) ->method('getSystemValue') - ->with($this->equalTo('objectstore')) - ->willReturn([ - 'class' => 'Test\Files\Mount\FakeObjectStore', - ]); + ->withConsecutive( + [$this->equalTo('objectstore_multibucket')], + [$this->equalTo('objectstore')], + )->willReturnOnConsecutiveCalls( + '', + [ + 'class' => 'Test\Files\Mount\FakeObjectStore', + ], + ); $this->user->method('getUID') ->willReturn('uid'); diff --git a/tests/lib/Files/Node/RootTest.php b/tests/lib/Files/Node/RootTest.php index ee86eab5675..5d8e2a4ac62 100644 --- a/tests/lib/Files/Node/RootTest.php +++ b/tests/lib/Files/Node/RootTest.php @@ -8,7 +8,7 @@ namespace Test\Files\Node; -use OC\Cache\CappedMemoryCache; +use OCP\Cache\CappedMemoryCache; use OC\Files\FileInfo; use OC\Files\Mount\Manager; use OC\Files\Node\Folder; diff --git a/tests/lib/Files/Storage/Wrapper/EncryptionTest.php b/tests/lib/Files/Storage/Wrapper/EncryptionTest.php index d26e5c499e7..ebb97a25c77 100644 --- a/tests/lib/Files/Storage/Wrapper/EncryptionTest.php +++ b/tests/lib/Files/Storage/Wrapper/EncryptionTest.php @@ -5,6 +5,7 @@ namespace Test\Files\Storage\Wrapper; use OC\Encryption\Exceptions\ModuleDoesNotExistsException; use OC\Encryption\Update; use OC\Encryption\Util; +use OC\Files\Cache\CacheEntry; use OC\Files\Storage\Temporary; use OC\Files\Storage\Wrapper\Encryption; use OC\Files\View; @@ -259,7 +260,7 @@ class EncryptionTest extends Storage { ->method('get') ->willReturnCallback( function ($path) use ($encrypted) { - return ['encrypted' => $encrypted, 'path' => $path, 'size' => 0, 'fileid' => 1]; + return new CacheEntry(['encrypted' => $encrypted, 'path' => $path, 'size' => 0, 'fileid' => 1]); } ); @@ -332,7 +333,7 @@ class EncryptionTest extends Storage { ->disableOriginalConstructor()->getMock(); $cache->expects($this->any()) ->method('get') - ->willReturn(['encrypted' => true, 'path' => '/test.txt', 'size' => 0, 'fileid' => 1]); + ->willReturn(new CacheEntry(['encrypted' => true, 'path' => '/test.txt', 'size' => 0, 'fileid' => 1])); $this->instance = $this->getMockBuilder('\OC\Files\Storage\Wrapper\Encryption') ->setConstructorArgs( @@ -910,7 +911,7 @@ class EncryptionTest extends Storage { if ($copyResult) { $cache->expects($this->once())->method('get') ->with($sourceInternalPath) - ->willReturn(['encrypted' => $encrypted, 'size' => 42]); + ->willReturn(new CacheEntry(['encrypted' => $encrypted, 'size' => 42])); if ($encrypted) { $instance->expects($this->once())->method('updateUnencryptedSize') ->with($mountPoint . $targetInternalPath, 42); diff --git a/tests/lib/Files/ViewTest.php b/tests/lib/Files/ViewTest.php index 7b735720ff1..86101d79a1e 100644 --- a/tests/lib/Files/ViewTest.php +++ b/tests/lib/Files/ViewTest.php @@ -7,7 +7,7 @@ namespace Test\Files; -use OC\Cache\CappedMemoryCache; +use OCP\Cache\CappedMemoryCache; use OC\Files\Cache\Watcher; use OC\Files\Filesystem; use OC\Files\Mount\MountPoint; @@ -2643,44 +2643,31 @@ class ViewTest extends \Test\TestCase { ]) ->getMock(); - $view - ->expects($this->at(0)) - ->method('is_file') - ->with('/new') - ->willReturn(false); - $view - ->expects($this->at(1)) - ->method('file_exists') - ->with('/new') - ->willReturn(true); - $view - ->expects($this->at(2)) - ->method('is_file') - ->with('/new/folder') - ->willReturn(false); - $view - ->expects($this->at(3)) - ->method('file_exists') - ->with('/new/folder') - ->willReturn(false); - $view - ->expects($this->at(4)) - ->method('mkdir') - ->with('/new/folder'); - $view - ->expects($this->at(5)) + $view->expects($this->exactly(3)) ->method('is_file') - ->with('/new/folder/structure') + ->withConsecutive( + ['/new'], + ['/new/folder'], + ['/new/folder/structure'], + ) ->willReturn(false); - $view - ->expects($this->at(6)) + $view->expects($this->exactly(3)) ->method('file_exists') - ->with('/new/folder/structure') - ->willReturn(false); - $view - ->expects($this->at(7)) + ->withConsecutive( + ['/new'], + ['/new/folder'], + ['/new/folder/structure'], + )->willReturnOnConsecutiveCalls( + true, + false, + false, + ); + $view->expects($this->exactly(2)) ->method('mkdir') - ->with('/new/folder/structure'); + ->withConsecutive( + ['/new/folder'], + ['/new/folder/structure'], + ); $this->assertTrue(self::invokePrivate($view, 'createParentDirectories', ['/new/folder/structure'])); } diff --git a/tests/lib/HelperStorageTest.php b/tests/lib/HelperStorageTest.php index 6d7ea513d3f..d3f480502b2 100644 --- a/tests/lib/HelperStorageTest.php +++ b/tests/lib/HelperStorageTest.php @@ -104,6 +104,9 @@ class HelperStorageTest extends \Test\TestCase { $extStorage->file_put_contents('extfile.txt', 'abcdefghijklmnopq'); $extStorage->getScanner()->scan(''); // update root size + $config = \OC::$server->getConfig(); + $config->setSystemValue('quota_include_external_storage', false); + \OC\Files\Filesystem::mount($extStorage, [], '/' . $this->user . '/files/ext'); $storageInfo = \OC_Helper::getStorageInfo(''); diff --git a/tests/lib/Http/Client/ClientTest.php b/tests/lib/Http/Client/ClientTest.php index 63835a4d4cd..141c6190cd9 100644 --- a/tests/lib/Http/Client/ClientTest.php +++ b/tests/lib/Http/Client/ClientTest.php @@ -75,35 +75,33 @@ class ClientTest extends \Test\TestCase { public function testGetProxyUriProxyHostWithPassword(): void { $this->config - ->expects($this->at(0)) + ->expects($this->exactly(3)) ->method('getSystemValue') - ->with( - $this->equalTo('proxy'), - $this->callback(function ($input) { - return $input === ''; - }) + ->withConsecutive( + [ + $this->equalTo('proxy'), + $this->callback(function ($input) { + return $input === ''; + }) + ], + [ + $this->equalTo('proxyuserpwd'), + $this->callback(function ($input) { + return $input === ''; + }) + ], + [ + $this->equalTo('proxyexclude'), + $this->callback(function ($input) { + return $input === []; + }) + ], ) - ->willReturn('foo'); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with( - $this->equalTo('proxyuserpwd'), - $this->callback(function ($input) { - return $input === ''; - }) - ) - ->willReturn('username:password'); - $this->config - ->expects($this->at(2)) - ->method('getSystemValue') - ->with( - $this->equalTo('proxyexclude'), - $this->callback(function ($input) { - return $input === []; - }) - ) - ->willReturn([]); + ->willReturnOnConsecutiveCalls( + 'foo', + 'username:password', + [], + ); $this->assertEquals([ 'http' => 'username:password@foo', 'https' => 'username:password@foo' @@ -112,35 +110,33 @@ class ClientTest extends \Test\TestCase { public function testGetProxyUriProxyHostWithPasswordAndExclude(): void { $this->config - ->expects($this->at(0)) - ->method('getSystemValue') - ->with( - $this->equalTo('proxy'), - $this->callback(function ($input) { - return $input === ''; - }) - ) - ->willReturn('foo'); - $this->config - ->expects($this->at(1)) + ->expects($this->exactly(3)) ->method('getSystemValue') - ->with( - $this->equalTo('proxyuserpwd'), - $this->callback(function ($input) { - return $input === ''; - }) + ->withConsecutive( + [ + $this->equalTo('proxy'), + $this->callback(function ($input) { + return $input === ''; + }) + ], + [ + $this->equalTo('proxyuserpwd'), + $this->callback(function ($input) { + return $input === ''; + }) + ], + [ + $this->equalTo('proxyexclude'), + $this->callback(function ($input) { + return $input === []; + }) + ], ) - ->willReturn('username:password'); - $this->config - ->expects($this->at(2)) - ->method('getSystemValue') - ->with( - $this->equalTo('proxyexclude'), - $this->callback(function ($input) { - return $input === []; - }) - ) - ->willReturn(['bar']); + ->willReturnOnConsecutiveCalls( + 'foo', + 'username:password', + ['bar'], + ); $this->assertEquals([ 'http' => 'username:password@foo', 'https' => 'username:password@foo', @@ -469,10 +465,16 @@ class ClientTest extends \Test\TestCase { public function testSetDefaultOptionsWithNotInstalled(): void { $this->config - ->expects($this->at(1)) + ->expects($this->exactly(2)) ->method('getSystemValue') - ->with('installed', false) - ->willReturn(false); + ->withConsecutive( + ['proxy', ''], + ['installed', false], + ) + ->willReturnOnConsecutiveCalls( + '', + false, + ); $this->certificateManager ->expects($this->never()) ->method('listCertificates'); @@ -500,20 +502,20 @@ class ClientTest extends \Test\TestCase { public function testSetDefaultOptionsWithProxy(): void { $this->config - ->expects($this->at(0)) + ->expects($this->exactly(4)) ->method('getSystemValue') - ->with('proxy', null) - ->willReturn('foo'); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('proxyuserpwd', null) - ->willReturn(null); - $this->config - ->expects($this->at(2)) - ->method('getSystemValue') - ->with('proxyexclude', []) - ->willReturn([]); + ->withConsecutive( + ['proxy', ''], + ['proxyuserpwd', ''], + ['proxyexclude', []], + ['installed', false], + ) + ->willReturnOnConsecutiveCalls( + 'foo', + '', + [], + true, + ); $this->certificateManager ->expects($this->once()) ->method('getAbsoluteBundlePath') @@ -547,20 +549,20 @@ class ClientTest extends \Test\TestCase { public function testSetDefaultOptionsWithProxyAndExclude(): void { $this->config - ->expects($this->at(0)) + ->expects($this->exactly(4)) ->method('getSystemValue') - ->with('proxy', null) - ->willReturn('foo'); - $this->config - ->expects($this->at(1)) - ->method('getSystemValue') - ->with('proxyuserpwd', null) - ->willReturn(null); - $this->config - ->expects($this->at(2)) - ->method('getSystemValue') - ->with('proxyexclude', []) - ->willReturn(['bar']); + ->withConsecutive( + ['proxy', ''], + ['proxyuserpwd', ''], + ['proxyexclude', []], + ['installed', false], + ) + ->willReturnOnConsecutiveCalls( + 'foo', + '', + ['bar'], + true, + ); $this->certificateManager ->expects($this->once()) ->method('getAbsoluteBundlePath') diff --git a/tests/lib/Http/Client/LocalAddressCheckerTest.php b/tests/lib/Http/Client/LocalAddressCheckerTest.php index 0bba1cee5f4..9f2f6c72993 100644 --- a/tests/lib/Http/Client/LocalAddressCheckerTest.php +++ b/tests/lib/Http/Client/LocalAddressCheckerTest.php @@ -96,6 +96,8 @@ class LocalAddressCheckerTest extends \Test\TestCase { ['10.0.0.1'], ['::'], ['::1'], + ['100.100.100.200'], + ['192.0.0.1'], ]; } @@ -116,6 +118,9 @@ class LocalAddressCheckerTest extends \Test\TestCase { ['another-host.local'], ['service.localhost'], ['!@#$'], // test invalid url + ['100.100.100.200'], + ['192.0.0.1'], + ['randomdomain.internal'], ]; } diff --git a/tests/lib/InstallerTest.php b/tests/lib/InstallerTest.php index c49f8bf76a5..352580337ad 100644 --- a/tests/lib/InstallerTest.php +++ b/tests/lib/InstallerTest.php @@ -340,7 +340,7 @@ u/spPSSVhaun5BA1FlphB2TkgnzlCmxJa63nFY045e/Jq+IKMcqqZl/092gbI2EQ $realTmpFile = \OC::$server->getTempManager()->getTemporaryFile('.tar.gz'); copy(__DIR__ . '/../data/testapp.tar.gz', $realTmpFile); $this->tempManager - ->expects($this->at(0)) + ->expects($this->once()) ->method('getTemporaryFile') ->with('.tar.gz') ->willReturn($realTmpFile); @@ -418,14 +418,14 @@ YwDVP+QmNRzx72jtqAN/Kc3CvQ9nkgYhU65B95aX0xA=', $realTmpFile = \OC::$server->getTempManager()->getTemporaryFile('.tar.gz'); copy(__DIR__ . '/../data/testapp1.tar.gz', $realTmpFile); $this->tempManager - ->expects($this->at(0)) + ->expects($this->once()) ->method('getTemporaryFile') ->with('.tar.gz') ->willReturn($realTmpFile); $realTmpFolder = \OC::$server->getTempManager()->getTemporaryFolder(); mkdir($realTmpFolder . '/testfolder'); $this->tempManager - ->expects($this->at(1)) + ->expects($this->once()) ->method('getTemporaryFolder') ->willReturn($realTmpFolder); $client = $this->createMock(IClient::class); @@ -502,13 +502,13 @@ YwDVP+QmNRzx72jtqAN/Kc3CvQ9nkgYhU65B95aX0xA=', $realTmpFile = \OC::$server->getTempManager()->getTemporaryFile('.tar.gz'); copy(__DIR__ . '/../data/testapp1.tar.gz', $realTmpFile); $this->tempManager - ->expects($this->at(0)) + ->expects($this->once()) ->method('getTemporaryFile') ->with('.tar.gz') ->willReturn($realTmpFile); $realTmpFolder = \OC::$server->getTempManager()->getTemporaryFolder(); $this->tempManager - ->expects($this->at(1)) + ->expects($this->once()) ->method('getTemporaryFolder') ->willReturn($realTmpFolder); $client = $this->createMock(IClient::class); @@ -575,30 +575,30 @@ MPLX6f5V9tCJtlH6ztmEcDROfvuVc0U3rEhqx2hphoyo+MZrPFpdcJL8KkIdMKbY ], ]; $this->appFetcher - ->expects($this->at(0)) + ->expects($this->atLeastOnce()) ->method('get') - ->willReturn($appArray); + ->willReturnOnConsecutiveCalls($appArray); $realTmpFile = \OC::$server->getTempManager()->getTemporaryFile('.tar.gz'); copy(__DIR__ . '/../data/testapp.tar.gz', $realTmpFile); $this->tempManager - ->expects($this->at(0)) + ->expects($this->atLeastOnce()) ->method('getTemporaryFile') ->with('.tar.gz') - ->willReturn($realTmpFile); + ->willReturnOnConsecutiveCalls($realTmpFile); $realTmpFolder = \OC::$server->getTempManager()->getTemporaryFolder(); $this->tempManager - ->expects($this->at(1)) + ->expects($this->atLeastOnce()) ->method('getTemporaryFolder') - ->willReturn($realTmpFolder); + ->willReturnOnConsecutiveCalls($realTmpFolder); $client = $this->createMock(IClient::class); $client ->expects($this->once()) ->method('get') ->with('https://example.com', ['sink' => $realTmpFile, 'timeout' => 120]); $this->clientService - ->expects($this->at(0)) + ->expects($this->atLeastOnce()) ->method('newClient') - ->willReturn($client); + ->willReturnOnConsecutiveCalls($client); $installer = $this->getInstaller(); $installer->downloadApp('testapp'); diff --git a/tests/lib/IntegrityCheck/CheckerTest.php b/tests/lib/IntegrityCheck/CheckerTest.php index 6f0c8e8ae85..37f6885c0ac 100644 --- a/tests/lib/IntegrityCheck/CheckerTest.php +++ b/tests/lib/IntegrityCheck/CheckerTest.php @@ -21,6 +21,7 @@ namespace Test\IntegrityCheck; +use OC\Core\Command\Maintenance\Mimetype\GenerateMimetypeFileBuilder; use OC\IntegrityCheck\Checker; use OC\IntegrityCheck\Helpers\AppLocator; use OC\IntegrityCheck\Helpers\EnvironmentHelper; @@ -87,12 +88,12 @@ class CheckerTest extends TestCase { $this->expectExceptionMessage('Exception message'); $this->fileAccessHelper - ->expects($this->at(0)) + ->expects($this->once()) ->method('assertDirectoryExists') ->with('NotExistingApp/appinfo') ->willThrowException(new \Exception('Exception message')); $this->fileAccessHelper - ->expects($this->at(1)) + ->expects($this->once()) ->method('is_writable') ->with('NotExistingApp/appinfo') ->willReturn(true); @@ -201,19 +202,16 @@ class CheckerTest extends TestCase { "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" }'; $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json' - ) - ->willReturn($signatureDataFile); - $this->fileAccessHelper - ->expects($this->at(1)) - ->method('file_get_contents') - ->with( - '/resources/codesigning/root.crt' - ) - ->willReturn(file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt')); + ->expects($this->exactly(2)) + ->method('file_get_contents') + ->withConsecutive( + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json'], + ['/resources/codesigning/root.crt'], + ) + ->willReturnOnConsecutiveCalls( + $signatureDataFile, + file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt') + ); $this->assertSame([], $this->checker->verifyAppSignature('SomeApp')); } @@ -243,19 +241,16 @@ class CheckerTest extends TestCase { "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEwTCCAqmgAwIBAgIUWv0iujufs5lUr0svCf\/qTQvoyKAwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIyNDk1M1oXDTE2MTEwMzIyNDk1M1owEjEQMA4GA1UEAwwHU29tZUFwcDCCAiIw\r\nDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK8q0x62agGSRBqeWsaeEwFfepMk\r\nF8cAobMMi50qHCv9IrOn\/ZH9l52xBrbIkErVmRjmly0d4JhD8Ymhidsh9ONKYl\/j\r\n+ishsZDM8eNNdp3Ew+fEYVvY1W7mR1qU24NWj0bzVsClI7hvPVIuw7AjfBDq1C5+\r\nA+ZSLSXYvOK2cEWjdxQfuNZwEZSjmA63DUllBIrm35IaTvfuyhU6BW9yHZxmb8+M\r\nw0xDv30D5UkE\/2N7Pa\/HQJLxCR+3zKibRK3nUyRDLSXxMkU9PnFNaPNX59VPgyj4\r\nGB1CFSToldJVPF4pzh7p36uGXZVxs8m3LFD4Ol8mhi7jkxDZjqFN46gzR0r23Py6\r\ndol9vfawGIoUwp9LvL0S7MvdRY0oazLXwClLP4OQ17zpSMAiCj7fgNT661JamPGj\r\nt5O7Zn2wA7I4ddDS\/HDTWCu98Zwc9fHIpsJPgCZ9awoqxi4Mnf7Pk9g5nnXhszGC\r\ncxxIASQKM+GhdzoRxKknax2RzUCwCzcPRtCj8AQT\/x\/mqN3PfRmlnFBNACUw9bpZ\r\nSOoNq2pCF9igftDWpSIXQ38pVpKLWowjjg3DVRmVKBgivHnUnVLyzYBahHPj0vaz\r\ntFtUFRaqXDnt+4qyUGyrT5h5pjZaTcHIcSB4PiarYwdVvgslgwnQzOUcGAzRWBD4\r\n6jV2brP5vFY3g6iPAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBACTY3CCHC+Z28gCf\r\nFWGKQ3wAKs+k4+0yoti0qm2EKX7rSGQ0PHSas6uW79WstC4Rj+DYkDtIhGMSg8FS\r\nHVGZHGBCc0HwdX+BOAt3zi4p7Sf3oQef70\/4imPoKxbAVCpd\/cveVcFyDC19j1yB\r\nBapwu87oh+muoeaZxOlqQI4UxjBlR\/uRSMhOn2UGauIr3dWJgAF4pGt7TtIzt+1v\r\n0uA6FtN1Y4R5O8AaJPh1bIG0CVvFBE58esGzjEYLhOydgKFnEP94kVPgJD5ds9C3\r\npPhEpo1dRpiXaF7WGIV1X6DI\/ipWvfrF7CEy6I\/kP1InY\/vMDjQjeDnJ\/VrXIWXO\r\nyZvHXVaN\/m+1RlETsH7YO\/QmxRue9ZHN3gvvWtmpCeA95sfpepOk7UcHxHZYyQbF\r\n49\/au8j+5tsr4A83xzsT1JbcKRxkAaQ7WDJpOnE5O1+H0fB+BaLakTg6XX9d4Fo7\r\n7Gin7hVWX7pL+JIyxMzME3LhfI61+CRcqZQIrpyaafUziPQbWIPfEs7h8tCOWyvW\r\nUO8ZLervYCB3j44ivkrxPlcBklDCqqKKBzDP9dYOtS\/P4RB1NkHA9+NTvmBpTonS\r\nSFXdg9fFMD7VfjDE3Vnk+8DWkVH5wBYowTAD7w9Wuzr7DumiAULexnP\/Y7xwxLv7\r\n4B+pXTAcRK0zECDEaX3npS8xWzrB\r\n-----END CERTIFICATE-----" }'; $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json' - ) - ->willReturn($signatureDataFile); - $this->fileAccessHelper - ->expects($this->at(1)) - ->method('file_get_contents') - ->with( - '/resources/codesigning/root.crt' - ) - ->willReturn(file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt')); + ->expects($this->exactly(2)) + ->method('file_get_contents') + ->withConsecutive( + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json'], + ['/resources/codesigning/root.crt'], + ) + ->willReturnOnConsecutiveCalls( + $signatureDataFile, + file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt') + ); $expected = [ 'EXCEPTION' => [ @@ -291,19 +286,16 @@ class CheckerTest extends TestCase { "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" }'; $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json' - ) - ->willReturn($signatureDataFile); - $this->fileAccessHelper - ->expects($this->at(1)) - ->method('file_get_contents') - ->with( - '/resources/codesigning/root.crt' - ) - ->willReturn(file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt')); + ->expects($this->exactly(2)) + ->method('file_get_contents') + ->withConsecutive( + [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json'], + ['/resources/codesigning/root.crt'], + ) + ->willReturnOnConsecutiveCalls( + $signatureDataFile, + file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt') + ); $expected = [ @@ -354,19 +346,16 @@ class CheckerTest extends TestCase { "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" }'; $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json' - ) - ->willReturn($signatureDataFile); - $this->fileAccessHelper - ->expects($this->at(1)) - ->method('file_get_contents') - ->with( - '/resources/codesigning/root.crt' - ) - ->willReturn(file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt')); + ->expects($this->exactly(2)) + ->method('file_get_contents') + ->withConsecutive( + [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json'], + ['/resources/codesigning/root.crt'], + ) + ->willReturnOnConsecutiveCalls( + $signatureDataFile, + file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt') + ); $expected = [ @@ -418,17 +407,15 @@ class CheckerTest extends TestCase { "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIExjCCAq6gAwIBAgIUHSJjhJqMwr+3TkoiQFg4SVVYQ1gwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIzMjc1NVoXDTE2MTEwMzIzMjc1NVowFzEVMBMGA1UEAwwMQW5vdGhlclNjb3Bl\r\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA33npb5RmUkXrDT+TbwMf\r\n0zQ33SlzsjoGxCrbSwJOn6leGGInJ6ZrdzLL0WTi\/dTpg+Y\/JS+72XWm5NSjaTxo\r\n7OHc3cQBwXQj4tN6j\/y5qqY0GDLYufEkx2rpazqt9lBSJ72u1bGl2yoOXzYCz5i0\r\n60KsJXC9K44LKzGsarzbwAgskSVNkjAsPgjnCWZmcl6icpLi5Fz9rs2UMOWbdvdI\r\nAROsn0eC9E\/akmXTy5YMu6bAIGpvjZFHzyA83FQRbvv5o1V5Gsye\/VQLEgh7rqfz\r\nT\/jgWifP+JgoeB6otzuRZ3fFsmbBiyCIRtIOzQQflozhUlWtmiEGwg4GySuMUjEH\r\nA1LF86LO+ZzDQgd2oYNKmrQ8O+EcLqx9BpV4AFhEvqdk7uycJYPHs6yl+yfbzTeJ\r\n2Xd0yVAfd9r\/iDr36clLj2bzEObdl9xzKjcCIXE4Q0G4Pur41\/BJUDK9PI390ccQ\r\nnFjjVYBMsC859OwW64tMP0zkM9Vv72LCaEzaR8jqH0j11catqxunr+StfMcmxLTN\r\nbqBJbSEq4ER3mJxCTI2UrIVmdQ7+wRxgv3QTDNOZyqrz2L8A1Rpb3h0APxtQv+oA\r\n8KIZYID5\/qsS2V2jITkMQ8Nd1W3b0cZhZ600z+znh3jLJ0TYLvwN6\/qBQTUDaM2o\r\ng1+icMqXIXIeKuoPCVVsG7cCAwEAATANBgkqhkiG9w0BAQUFAAOCAgEAHc4F\/kOV\r\nHc8In5MmGg2YtjwZzjdeoC5TIPZczRqz0B+wRbJzN6aYryKZKLmP+wKpgRnJWDzp\r\nrgKGyyEQIAfK63DEv4B9p4N1B+B3aeMKsSpVcw7wbFTD57V5A7pURGoo31d0mw5L\r\nUIXZ2u+TUfGbzucMxLdFhTwjGpz9M6Kkm\/POxmV0tvLija5LdbdKnYR9BFmyu4IX\r\nqyoIAtComATNLl+3URu3SZxhE3NxhzMz+eAeNfh1KuIf2gWIIeDCXalVSJLym+OQ\r\nHFDpqRhJqfTMprrRlmmU7Zntgbj8\/RRZuXnBvH9cQ2KykLOb4UoCPlGUqOqKyP9m\r\nDJSFRiMJfpgMQUaJk1TLhKF+IR6FnmwURLEtkONJumtDQju9KaWPlhueONdyGi0p\r\nqxLVUo1Vb52XnPhk2GEEduxpDc9V5ePJ+pdcEdMifY\/uPNBRuBj2c87yq1DLH+U4\r\n3XzP1MlwjnBWZYuoFo0j6Jq0r\/MG6HjGdmkGIsRoheRi8Z8Scz5AW5QRkNz8pKop\r\nTELFqQy9g6TyQzzC8t6HZcpNe842ZUk4raEAbCZe\/XqxWMw5svPgNceBqM3fh7sZ\r\nBSykOHLaL8kiRO\/IS3y1yZEAuiWBvtxcTNLzBb+hdRpm2y8\/qH\/pKo+CMj1VzjNT\r\nD8YRQg0cjmDytJzHDrtV\/aTc9W1aPHun0vw=\r\n-----END CERTIFICATE-----" }'; $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with(\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json') - ->willReturn($signatureDataFile); - $this->fileAccessHelper - ->expects($this->at(1)) - ->method('file_get_contents') - ->with( - '/resources/codesigning/root.crt' - ) - ->willReturn(file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt')); + ->expects($this->exactly(2)) + ->method('file_get_contents') + ->withConsecutive( + [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//appinfo/signature.json'], + ['/resources/codesigning/root.crt'], + )->willReturnOnConsecutiveCalls( + $signatureDataFile, + file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt') + ); $expected = [ 'EXCEPTION' => [ @@ -464,17 +451,15 @@ class CheckerTest extends TestCase { "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" }'; $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with(\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json') - ->willReturn($signatureDataFile); - $this->fileAccessHelper - ->expects($this->at(1)) - ->method('file_get_contents') - ->with( - '/resources/codesigning/root.crt' - ) - ->willReturn(file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt')); + ->expects($this->exactly(2)) + ->method('file_get_contents') + ->withConsecutive( + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//appinfo/signature.json'], + ['/resources/codesigning/root.crt'], + )->willReturnOnConsecutiveCalls( + $signatureDataFile, + file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt') + ); $this->assertSame([], $this->checker->verifyAppSignature('SomeApp')); } @@ -485,11 +470,11 @@ class CheckerTest extends TestCase { $this->expectExceptionMessage('Exception message'); $this->fileAccessHelper - ->expects($this->at(0)) + ->expects($this->once()) ->method('assertDirectoryExists') ->will($this->throwException(new \Exception('Exception message'))); $this->fileAccessHelper - ->expects($this->at(1)) + ->expects($this->once()) ->method('is_writable') ->with(__DIR__ . '/core') ->willReturn(true); @@ -509,11 +494,11 @@ class CheckerTest extends TestCase { $this->expectExceptionMessageMatches('/[a-zA-Z\\/_-]+ is not writable/'); $this->fileAccessHelper - ->expects($this->at(0)) + ->expects($this->once()) ->method('assertDirectoryExists') ->will($this->throwException(new \Exception('Exception message'))); $this->fileAccessHelper - ->expects($this->at(1)) + ->expects($this->once()) ->method('is_writable') ->with(__DIR__ . '/core') ->willReturn(false); @@ -706,19 +691,15 @@ class CheckerTest extends TestCase { "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" }'; $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json' - ) - ->willReturn($signatureDataFile); - $this->fileAccessHelper - ->expects($this->at(1)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt' - ) - ->willReturn(file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt')); + ->expects($this->exactly(2)) + ->method('file_get_contents') + ->withConsecutive( + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json'], + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt'], + )->willReturnOnConsecutiveCalls( + $signatureDataFile, + file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt') + ); $this->assertSame([], $this->checker->verifyCoreSignature()); } @@ -747,24 +728,46 @@ class CheckerTest extends TestCase { "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" }'; $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json' - ) - ->willReturn($signatureDataFile); - $this->fileAccessHelper - ->expects($this->at(1)) + ->expects($this->exactly(2)) ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/resources/codesigning/root.crt' + ->withConsecutive( + [\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/core/signature.json'], + [\OC::$SERVERROOT . '/tests/data/integritycheck/htaccessWithValidModifiedContent/resources/codesigning/root.crt'], ) - ->willReturn(file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt')); + ->willReturnOnConsecutiveCalls( + $signatureDataFile, + file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt') + ); $this->assertSame([], $this->checker->verifyCoreSignature()); } + /** + * See inline instruction on how to update the test assets when changing mimetypealiases.dist.json + */ public function testVerifyCoreSignatureWithModifiedMimetypelistSignatureData() { + $shippedMimetypeAliases = (array)json_decode(file_get_contents(\OC::$SERVERROOT . '/resources/config/mimetypealiases.dist.json')); + $allAliases = array_merge($shippedMimetypeAliases, ['my-custom/mimetype' => 'custom']); + + $this->mimeTypeDetector + ->method('getOnlyDefaultAliases') + ->willReturn($shippedMimetypeAliases); + + $this->mimeTypeDetector + ->method('getAllAliases') + ->willReturn($allAliases); + + $oldMimetypeList = new GenerateMimetypeFileBuilder(); + $all = $this->mimeTypeDetector->getAllAliases(); + $newFile = $oldMimetypeList->generateFile($all); + + // When updating the mimetype list the test assets need to be updated as well + // 1. Update core/js/mimetypelist.js with the new generated js by running the test with the next line uncommented: + // file_put_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js', $newFile); + // 2. Update signature.json using the following occ command: + // occ integrity:sign-core --privateKey=./tests/data/integritycheck/core.key --certificate=./tests/data/integritycheck/core.crt --path=./tests/data/integritycheck/mimetypeListModified + self::assertEquals($newFile, file_get_contents(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/js/mimetypelist.js')); + $this->environmentHelper ->expects($this->once()) ->method('getChannel') @@ -775,264 +778,18 @@ class CheckerTest extends TestCase { ->with('integrity.check.disabled', false) ->willReturn(false); - $this->mimeTypeDetector - ->expects($this->once()) - ->method('getOnlyDefaultAliases') - ->willReturn( - [ - '_comment' => 'Array of mimetype aliases.', - '_comment2' => 'Any changes you make here will be overwritten on an update of Nextcloud.', - '_comment3' => 'Put any custom mappings in a new file mimetypealiases.json in the config/ folder of Nextcloud', - '_comment4' => 'After any change to mimetypealiases.json run:', - '_comment5' => './occ maintenance:mimetype:update-js', - '_comment6' => 'Otherwise your update won\'t propagate through the system.', - 'application/coreldraw' => 'image', - 'application/epub+zip' => 'text', - 'application/font-sfnt' => 'image', - 'application/font-woff' => 'image', - 'application/gpx+xml' => 'location', - 'application/illustrator' => 'image', - 'application/javascript' => 'text/code', - 'application/json' => 'text/code', - 'application/msaccess' => 'file', - 'application/msexcel' => 'x-office/spreadsheet', - 'application/msonenote' => 'x-office/document', - 'application/mspowerpoint' => 'x-office/presentation', - 'application/msword' => 'x-office/document', - 'application/octet-stream' => 'file', - 'application/postscript' => 'image', - 'application/rss+xml' => 'application/xml', - 'application/vnd.android.package-archive' => 'package/x-generic', - 'application/vnd.lotus-wordpro' => 'x-office/document', - 'application/vnd.garmin.tcx+xml' => 'location', - 'application/vnd.google-earth.kml+xml' => 'location', - 'application/vnd.google-earth.kmz' => 'location', - 'application/vnd.ms-excel' => 'x-office/spreadsheet', - 'application/vnd.ms-excel.addin.macroEnabled.12' => 'x-office/spreadsheet', - 'application/vnd.ms-excel.sheet.binary.macroEnabled.12' => 'x-office/spreadsheet', - 'application/vnd.ms-excel.sheet.macroEnabled.12' => 'x-office/spreadsheet', - 'application/vnd.ms-excel.template.macroEnabled.12' => 'x-office/spreadsheet', - 'application/vnd.ms-fontobject' => 'image', - 'application/vnd.ms-powerpoint' => 'x-office/presentation', - 'application/vnd.ms-powerpoint.addin.macroEnabled.12' => 'x-office/presentation', - 'application/vnd.ms-powerpoint.presentation.macroEnabled.12' => 'x-office/presentation', - 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12' => 'x-office/presentation', - 'application/vnd.ms-powerpoint.template.macroEnabled.12' => 'x-office/presentation', - 'application/vnd.ms-visio.drawing.macroEnabled.12' => 'application/vnd.visio', - 'application/vnd.ms-visio.drawing' => 'application/vnd.visio', - 'application/vnd.ms-visio.stencil.macroEnabled.12' => 'application/vnd.visio', - 'application/vnd.ms-visio.stencil' => 'application/vnd.visio', - 'application/vnd.ms-visio.template.macroEnabled.12' => 'application/vnd.visio', - 'application/vnd.ms-visio.template' => 'application/vnd.visio', - 'application/vnd.ms-word.document.macroEnabled.12' => 'x-office/document', - 'application/vnd.ms-word.template.macroEnabled.12' => 'x-office/document', - 'application/vnd.oasis.opendocument.presentation' => 'x-office/presentation', - 'application/vnd.oasis.opendocument.presentation-template' => 'x-office/presentation', - 'application/vnd.oasis.opendocument.spreadsheet' => 'x-office/spreadsheet', - 'application/vnd.oasis.opendocument.spreadsheet-template' => 'x-office/spreadsheet', - 'application/vnd.oasis.opendocument.text' => 'x-office/document', - 'application/vnd.oasis.opendocument.text-master' => 'x-office/document', - 'application/vnd.oasis.opendocument.text-template' => 'x-office/document', - 'application/vnd.oasis.opendocument.graphics' => 'x-office/drawing', - 'application/vnd.oasis.opendocument.graphics-template' => 'x-office/drawing', - 'application/vnd.oasis.opendocument.text-web' => 'x-office/document', - 'application/vnd.oasis.opendocument.text-flat-xml' => 'x-office/document', - 'application/vnd.oasis.opendocument.spreadsheet-flat-xml' => 'x-office/spreadsheet', - 'application/vnd.oasis.opendocument.graphics-flat-xml' => 'x-office/drawing', - 'application/vnd.oasis.opendocument.presentation-flat-xml' => 'x-office/presentation', - 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'x-office/presentation', - 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'x-office/presentation', - 'application/vnd.openxmlformats-officedocument.presentationml.template' => 'x-office/presentation', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'x-office/spreadsheet', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 'x-office/spreadsheet', - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'x-office/document', - 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => 'x-office/document', - 'application/vnd.visio' => 'x-office/document', - 'application/vnd.wordperfect' => 'x-office/document', - 'application/x-7z-compressed' => 'package/x-generic', - 'application/x-bzip2' => 'package/x-generic', - 'application/x-cbr' => 'text', - 'application/x-compressed' => 'package/x-generic', - 'application/x-dcraw' => 'image', - 'application/x-deb' => 'package/x-generic', - 'application/x-fictionbook+xml' => 'text', - 'application/x-font' => 'image', - 'application/x-gimp' => 'image', - 'application/x-gzip' => 'package/x-generic', - 'application/x-iwork-keynote-sffkey' => 'x-office/presentation', - 'application/x-iwork-numbers-sffnumbers' => 'x-office/spreadsheet', - 'application/x-iwork-pages-sffpages' => 'x-office/document', - 'application/x-mobipocket-ebook' => 'text', - 'application/x-perl' => 'text/code', - 'application/x-photoshop' => 'image', - 'application/x-php' => 'text/code', - 'application/x-rar-compressed' => 'package/x-generic', - 'application/x-tar' => 'package/x-generic', - 'application/x-tex' => 'text', - 'application/xml' => 'text/html', - 'application/yaml' => 'text/code', - 'application/zip' => 'package/x-generic', - 'database' => 'file', - 'httpd/unix-directory' => 'dir', - 'text/css' => 'text/code', - 'text/csv' => 'x-office/spreadsheet', - 'text/html' => 'text/code', - 'text/x-c' => 'text/code', - 'text/x-c++src' => 'text/code', - 'text/x-h' => 'text/code', - 'text/x-java-source' => 'text/code', - 'text/x-ldif' => 'text/code', - 'text/x-python' => 'text/code', - 'text/x-shellscript' => 'text/code', - 'web' => 'text/code', - 'application/internet-shortcut' => 'link', - 'application/km' => 'mindmap', - 'application/x-freemind' => 'mindmap', - 'application/vnd.xmind.workbook' => 'mindmap' - ]); - - $this->mimeTypeDetector - ->expects($this->once()) - ->method('getAllAliases') - ->willReturn( - [ - '_comment' => 'Array of mimetype aliases.', - '_comment2' => 'Any changes you make here will be overwritten on an update of Nextcloud.', - '_comment3' => 'Put any custom mappings in a new file mimetypealiases.json in the config/ folder of Nextcloud', - '_comment4' => 'After any change to mimetypealiases.json run:', - '_comment5' => './occ maintenance:mimetype:update-js', - '_comment6' => 'Otherwise your update won\'t propagate through the system.', - 'application/coreldraw' => 'image', - 'application/test' => 'image', - 'application/epub+zip' => 'text', - 'application/font-sfnt' => 'image', - 'application/font-woff' => 'image', - 'application/gpx+xml' => 'location', - 'application/illustrator' => 'image', - 'application/javascript' => 'text/code', - 'application/json' => 'text/code', - 'application/msaccess' => 'file', - 'application/msexcel' => 'x-office/spreadsheet', - 'application/msonenote' => 'x-office/document', - 'application/mspowerpoint' => 'x-office/presentation', - 'application/msword' => 'x-office/document', - 'application/octet-stream' => 'file', - 'application/postscript' => 'image', - 'application/rss+xml' => 'application/xml', - 'application/vnd.android.package-archive' => 'package/x-generic', - 'application/vnd.lotus-wordpro' => 'x-office/document', - 'application/vnd.garmin.tcx+xml' => 'location', - 'application/vnd.google-earth.kml+xml' => 'location', - 'application/vnd.google-earth.kmz' => 'location', - 'application/vnd.ms-excel' => 'x-office/spreadsheet', - 'application/vnd.ms-excel.addin.macroEnabled.12' => 'x-office/spreadsheet', - 'application/vnd.ms-excel.sheet.binary.macroEnabled.12' => 'x-office/spreadsheet', - 'application/vnd.ms-excel.sheet.macroEnabled.12' => 'x-office/spreadsheet', - 'application/vnd.ms-excel.template.macroEnabled.12' => 'x-office/spreadsheet', - 'application/vnd.ms-fontobject' => 'image', - 'application/vnd.ms-powerpoint' => 'x-office/presentation', - 'application/vnd.ms-powerpoint.addin.macroEnabled.12' => 'x-office/presentation', - 'application/vnd.ms-powerpoint.presentation.macroEnabled.12' => 'x-office/presentation', - 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12' => 'x-office/presentation', - 'application/vnd.ms-powerpoint.template.macroEnabled.12' => 'x-office/presentation', - 'application/vnd.ms-visio.drawing.macroEnabled.12' => 'application/vnd.visio', - 'application/vnd.ms-visio.drawing' => 'application/vnd.visio', - 'application/vnd.ms-visio.stencil.macroEnabled.12' => 'application/vnd.visio', - 'application/vnd.ms-visio.stencil' => 'application/vnd.visio', - 'application/vnd.ms-visio.template.macroEnabled.12' => 'application/vnd.visio', - 'application/vnd.ms-visio.template' => 'application/vnd.visio', - 'application/vnd.ms-word.document.macroEnabled.12' => 'x-office/document', - 'application/vnd.ms-word.template.macroEnabled.12' => 'x-office/document', - 'application/vnd.oasis.opendocument.presentation' => 'x-office/presentation', - 'application/vnd.oasis.opendocument.presentation-template' => 'x-office/presentation', - 'application/vnd.oasis.opendocument.spreadsheet' => 'x-office/spreadsheet', - 'application/vnd.oasis.opendocument.spreadsheet-template' => 'x-office/spreadsheet', - 'application/vnd.oasis.opendocument.text' => 'x-office/document', - 'application/vnd.oasis.opendocument.text-master' => 'x-office/document', - 'application/vnd.oasis.opendocument.text-template' => 'x-office/document', - 'application/vnd.oasis.opendocument.graphics' => 'x-office/drawing', - 'application/vnd.oasis.opendocument.graphics-template' => 'x-office/drawing', - 'application/vnd.oasis.opendocument.text-web' => 'x-office/document', - 'application/vnd.oasis.opendocument.text-flat-xml' => 'x-office/document', - 'application/vnd.oasis.opendocument.spreadsheet-flat-xml' => 'x-office/spreadsheet', - 'application/vnd.oasis.opendocument.graphics-flat-xml' => 'x-office/drawing', - 'application/vnd.oasis.opendocument.presentation-flat-xml' => 'x-office/presentation', - 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'x-office/presentation', - 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'x-office/presentation', - 'application/vnd.openxmlformats-officedocument.presentationml.template' => 'x-office/presentation', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'x-office/spreadsheet', - 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 'x-office/spreadsheet', - 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'x-office/document', - 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => 'x-office/document', - 'application/vnd.visio' => 'x-office/document', - 'application/vnd.wordperfect' => 'x-office/document', - 'application/x-7z-compressed' => 'package/x-generic', - 'application/x-bzip2' => 'package/x-generic', - 'application/x-cbr' => 'text', - 'application/x-compressed' => 'package/x-generic', - 'application/x-dcraw' => 'image', - 'application/x-deb' => 'package/x-generic', - 'application/x-fictionbook+xml' => 'text', - 'application/x-font' => 'image', - 'application/x-gimp' => 'image', - 'application/x-gzip' => 'package/x-generic', - 'application/x-iwork-keynote-sffkey' => 'x-office/presentation', - 'application/x-iwork-numbers-sffnumbers' => 'x-office/spreadsheet', - 'application/x-iwork-pages-sffpages' => 'x-office/document', - 'application/x-mobipocket-ebook' => 'text', - 'application/x-perl' => 'text/code', - 'application/x-photoshop' => 'image', - 'application/x-php' => 'text/code', - 'application/x-rar-compressed' => 'package/x-generic', - 'application/x-tar' => 'package/x-generic', - 'application/x-tex' => 'text', - 'application/xml' => 'text/html', - 'application/yaml' => 'text/code', - 'application/zip' => 'package/x-generic', - 'database' => 'file', - 'httpd/unix-directory' => 'dir', - 'text/css' => 'text/code', - 'text/csv' => 'x-office/spreadsheet', - 'text/html' => 'text/code', - 'text/x-c' => 'text/code', - 'text/x-c++src' => 'text/code', - 'text/x-h' => 'text/code', - 'text/x-java-source' => 'text/code', - 'text/x-ldif' => 'text/code', - 'text/x-python' => 'text/code', - 'text/x-shellscript' => 'text/code', - 'web' => 'text/code', - 'application/internet-shortcut' => 'link', - 'application/km' => 'mindmap', - 'application/x-freemind' => 'mindmap', - 'application/vnd.xmind.workbook' => 'mindmap' - ]); - $this->environmentHelper ->expects($this->any()) ->method('getServerRoot') ->willReturn(\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified'); - $signatureDataFile = '{ - "hashes": { - "core\/js\/mimetypelist.js": "94195a260a005dac543c3f6aa504f1b28e0078297fe94a4f52f012c16c109f0323eecc9f767d6949f860dfe454625fcaf1dc56f87bb8350975d8f006bbbdf14a" - }, - "signature": "BYPMrU+2vzSOOjSFcRPsWphv0uXQ+Vu6yC7FL6V0iM4WXcAkTK1e5OjkHFqUBNIDxg0AWB14ogUFRGDr+Qh+AqDRaX1u2ST2BhO1mgVh4JaqVOhlnDgWg8NPRMaVqvMy6Rfmyj57D1vmDmbVGQmnaIxEot84mOx4MP6sgZIVOMEe2itlmNwp1ogG6t61wpj4dFe73tYPDePWh0j+TmW8a\/Ry67wIhWHHhSGWIhhYRi8NmfW0oLhL1tgze5+Oo4pvgIgJq47BOYGu4YnfY3w8PB\/sQ5bPIvd\/+CTt\/1RASoadEfLd0MjLFEVEAj3uVGMq1kv7gK4bisXrKJS\/dbCwM+iJQfVFIVjwzuPH1QLbvSEsVUkJKVM4iS4aKiIty5Q760ufuSkZUoZoBrJCy\/PfC6Dc9hmOg1gXiPA9Tzje7L\/V8b0ULmFdnZtITYjEXd52yhfB\/P6qsKOm3HM8bM\/qoL3ra7\/hwe\/dyEi45eJbrbw9lywWwK8Q+fY92o2PCQgVkPYgK0VUOxPMZ6CtBM5OOe9lkuUZzGzCl\/sWZzUiSiXQME\/CDmi2T\/cX65eXzPkFCv2503OKOGtY7fFgBOg2DGXz0\/SEubpeuhs3P+mc\/v\/TUbhJ3hOXD7OBWruTWLbJ4WZyNj4k\/NaXLi1ktbsIB5L19wAFrRLACzCD+ZkVSMs=", - "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" -}'; - $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/signature.json' - ) - ->willReturn($signatureDataFile); + + $signatureDataFile = file_get_contents(__DIR__ .'/../../data/integritycheck/mimetypeListModified/core/signature.json'); $this->fileAccessHelper - ->expects($this->at(1)) ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/resources/codesigning/root.crt' - ) - ->willReturn(file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt')); + ->willReturnMap([ + [\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/core/signature.json', $signatureDataFile], + [\OC::$SERVERROOT . '/tests/data/integritycheck/mimetypeListModified/resources/codesigning/root.crt', file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt')], + ]); $this->assertSame([], $this->checker->verifyCoreSignature()); } @@ -1061,19 +818,15 @@ class CheckerTest extends TestCase { "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" }'; $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json' - ) - ->willReturn($signatureDataFile); - $this->fileAccessHelper - ->expects($this->at(1)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt' - ) - ->willReturn(file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt')); + ->expects($this->exactly(2)) + ->method('file_get_contents') + ->withConsecutive( + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json'], + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt'], + )->willReturnOnConsecutiveCalls( + $signatureDataFile, + file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt') + ); $this->assertSame([], $this->checker->verifyCoreSignature()); } @@ -1102,19 +855,15 @@ class CheckerTest extends TestCase { "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" }'; $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//core/signature.json' - ) - ->willReturn($signatureDataFile); - $this->fileAccessHelper - ->expects($this->at(1)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt' - ) - ->willReturn(file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt')); + ->expects($this->exactly(2)) + ->method('file_get_contents') + ->withConsecutive( + [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//core/signature.json'], + [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt'], + )->willReturnOnConsecutiveCalls( + $signatureDataFile, + file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt') + ); $expected = [ 'EXCEPTION' => [ @@ -1149,19 +898,15 @@ class CheckerTest extends TestCase { "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUc\/0FxYrsgSs9rDxp03EJmbjN0NwwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIxMDMzM1oXDTE2MTEwMzIxMDMzM1owDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBALb6EgHpkAqZbO5vRO8XSh7G7XGWHw5s\r\niOf4RwPXR6SE9bWZEm\/b72SfWk\/\/J6AbrD8WiOzBuT\/ODy6k5T1arEdHO+Pux0W1\r\nMxYJJI4kH74KKgMpC0SB0Rt+8WrMqV1r3hhJ46df6Xr\/xolP3oD+eLbShPcblhdS\r\nVtkZEkoev8Sh6L2wDCeHDyPxzvj1w2dTdGVO9Kztn0xIlyfEBakqvBWtcxyi3Ln0\r\nklnxlMx3tPDUE4kqvpia9qNiB1AN2PV93eNr5\/2riAzIssMFSCarWCx0AKYb54+d\r\nxLpcYFyqPJ0ydBCkF78DD45RCZet6PNYkdzgbqlUWEGGomkuDoJbBg4wzgzO0D77\r\nH87KFhYW8tKFFvF1V3AHl\/sFQ9tDHaxM9Y0pZ2jPp\/ccdiqnmdkBxBDqsiRvHvVB\r\nCn6qpb4vWGFC7vHOBfYspmEL1zLlKXZv3ezMZEZw7O9ZvUP3VO\/wAtd2vUW8UFiq\r\ns2v1QnNLN6jNh51obcwmrBvWhJy9vQIdtIjQbDxqWTHh1zUSrw9wrlklCBZ\/zrM0\r\ni8nfCFwTxWRxp3H9KoECzO\/zS5R5KIS7s3\/wq\/w9T2Ie4rcecgXwDizwnn0C\/aKc\r\nbDIjujpL1s9HO05pcD\/V3wKcPZ1izymBkmMyIbL52iRVN5FTVHeZdXPpFuq+CTQJ\r\nQ238lC+A\/KOVAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAGoKTnh8RfJV4sQItVC2\r\nAvfJagkrIqZ3iiQTUBQGTKBsTnAqE1H7QgUSV9vSd+8rgvHkyZsRjmtyR1e3A6Ji\r\noNCXUbExC\/0iCPUqdHZIVb+Lc\/vWuv4ByFMybGPydgtLoEUX2ZrKFWmcgZFDUSRd\r\n9Uj26vtUhCC4bU4jgu6hIrR9IuxOBLQUxGTRZyAcXvj7obqRAEZwFAKQgFpfpqTb\r\nH+kjcbZSaAlLVSF7vBc1syyI8RGYbqpwvtREqJtl5IEIwe6huEqJ3zPnlP2th\/55\r\ncf3Fovj6JJgbb9XFxrdnsOsDOu\/tpnaRWlvv5ib4+SzG5wWFT5UUEo4Wg2STQiiX\r\nuVSRQxK1LE1yg84bs3NZk9FSQh4B8vZVuRr5FaJsZZkwlFlhRO\/\/+TJtXRbyNgsf\r\noMRZGi8DLGU2SGEAHcRH\/QZHq\/XDUWVzdxrSBYcy7GSpT7UDVzGv1rEJUrn5veP1\r\n0KmauAqtiIaYRm4f6YBsn0INcZxzIPZ0p8qFtVZBPeHhvQtvOt0iXI\/XUxEWOa2F\r\nK2EqhErgMK\/N07U1JJJay5tYZRtvkGq46oP\/5kQG8hYST0MDK6VihJoPpvCmAm4E\r\npEYKQ96x6A4EH9Y9mZlYozH\/eqmxPbTK8n89\/p7Ydun4rI+B2iiLnY8REWWy6+UQ\r\nV204fGUkJqW5CrKy3P3XvY9X\r\n-----END CERTIFICATE-----" }'; $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//core/signature.json' - ) - ->willReturn($signatureDataFile); - $this->fileAccessHelper - ->expects($this->at(1)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt' - ) - ->willReturn(file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt')); + ->expects($this->exactly(2)) + ->method('file_get_contents') + ->withConsecutive( + [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//core/signature.json'], + [\OC::$SERVERROOT . '/tests/data/integritycheck/appWithInvalidData//resources/codesigning/root.crt'], + )->willReturnOnConsecutiveCalls( + $signatureDataFile, + file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt') + ); $expected = [ 'INVALID_HASH' => [ @@ -1211,19 +956,15 @@ class CheckerTest extends TestCase { "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEvjCCAqagAwIBAgIUPYoweUxCPqbDW4ntuh7QvgyqSrgwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIyNDIwNloXDTE2MTEwMzIyNDIwNlowDzENMAsGA1UEAwwEY29yZTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJui3nDbjOIjxNnthdBZplphujsN6u8K\r\nQ\/62zAuSwzXVp0+3IMgM\/2sepklVE8YfCyVJ5+SUJqnqHoUWVRVfs8jL0wW6nrHM\r\n\/lsscAguWCee4iAdNOqI9kq4+DUau8J45e62XA9mrAo\/8\/NKzFE2y2WduDoQZcm+\r\n8+dwcUUHXw2jl8dfrmvEMYSqTNDdb4rGmQpeV+dr9BLqr+x03U1Q08qCG9j7mSOz\r\ncvJENjOvC5uzAh5LCuCgxqG4o+mPzB0FtNnwoRRu6IsF3Y3KacRqPc30fB\/iXDn5\r\nBPr14uNxTTYWoZJ1F0tZrLzRbXdjJJOC+dnQurTtXWZ8WjPB1BWQYK7fW6t82mkN\r\n2Qe2xen99gs9nX5yY\/sHM3TKSJdM7AVCEv\/emW3gNjkvWTtRlN\/Nc7X2ckNwXcvo\r\n0yi3fSPjzXpDgLbhp1FzrMlHDn1VzmRT3r8wLByWa\/hsxrJDsBzwunMJYhXhmeKb\r\n3wX0tN\/EUJTWBntpwVOIGnRPD51oBoQUOMaEAq\/kz8PgN181bWZkJbRuf+FWkijQ\r\no+HR2lVF1jWXXst5Uc+s9HN81Uly7X4O9MMg0QxT4+wymtGDs6AOkwMi9rgBTrRB\r\n3tLU3XL2UIwRXgmd8cPtTu\/I6Bm7LdyaYtZ3yJTxRewq3nZdWypqBhD8uhpIYVkf\r\no4bxmGkVAQVTAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAKKAX5EHgU1grODnJ0of\r\nspFpgB1K67YvclNUyuU6NQ6zBJx1\/w1RnM7uxLcxiiWj1BbUhwZQ0ojmEHeUyi6O\r\nGrDVajwhTccDMmja3u5adhEncx65\/H+lD85IPRRkS2qBDssMDdJHhZ0uI+40nI7M\r\nMq1kFjl+6wiuqZXqps66DuLbk45g\/ZlrFIrIo3Ix5vj0OVqwT+gO4LYirJK6KgVS\r\nUttbcEsc\/yKU9ThnM8\/n4m2jstZXfzKPgOsJrQcZrFOtpj+CWmBzVElBSPlDT3Nh\r\nHSgOeTFJ8bQBxj2iG5dLA+JZJQKxyJ1gy2ZtxIJ2GyvLtSe8NUSqvfPWOaAKEUV2\r\ngniytnEFLr+PcD+9EGux6jZNuj6HmtWVThTfD5VGFmtlVU2z71ZRYY0kn6J3mmFc\r\nS2ecEcCUwqG5YNLncEUCyZhC2klWql2SHyGctCEyWWY7ikIDjVzYt2EbcFvLNBnP\r\ntybN1TYHRRZxlug00CCoOE9EZfk46FkZpDvU6KmqJRofkNZ5sj+SffyGcwYwNrDH\r\nKqe8m+9lHf3CRTIDeMu8r2xl1I6M6ZZfjabbmVP9Jd6WN4s6f1FlXDWzhlT1N0Qw\r\nGzJj6xB+SPtS3UV05tBlvbfA4e06D5G9uD7Q8ONcINtMS0xsSJ2oo82AqlpvlF\/q\r\noj7YKHsaTVGA+FxBktZHfoxD\r\n-----END CERTIFICATE-----" }'; $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json' - ) - ->willReturn($signatureDataFile); - $this->fileAccessHelper - ->expects($this->at(1)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt' - ) - ->willReturn(file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt')); + ->expects($this->exactly(2)) + ->method('file_get_contents') + ->withConsecutive( + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json'], + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt'], + )->willReturnOnConsecutiveCalls( + $signatureDataFile, + file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt') + ); $expected = [ 'EXCEPTION' => [ @@ -1258,19 +999,15 @@ class CheckerTest extends TestCase { "certificate": "-----BEGIN CERTIFICATE-----\r\nMIIEwTCCAqmgAwIBAgIUWv0iujufs5lUr0svCf\/qTQvoyKAwDQYJKoZIhvcNAQEF\r\nBQAwIzEhMB8GA1UECgwYb3duQ2xvdWQgQ29kZSBTaWduaW5nIENBMB4XDTE1MTEw\r\nMzIyNDk1M1oXDTE2MTEwMzIyNDk1M1owEjEQMA4GA1UEAwwHU29tZUFwcDCCAiIw\r\nDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK8q0x62agGSRBqeWsaeEwFfepMk\r\nF8cAobMMi50qHCv9IrOn\/ZH9l52xBrbIkErVmRjmly0d4JhD8Ymhidsh9ONKYl\/j\r\n+ishsZDM8eNNdp3Ew+fEYVvY1W7mR1qU24NWj0bzVsClI7hvPVIuw7AjfBDq1C5+\r\nA+ZSLSXYvOK2cEWjdxQfuNZwEZSjmA63DUllBIrm35IaTvfuyhU6BW9yHZxmb8+M\r\nw0xDv30D5UkE\/2N7Pa\/HQJLxCR+3zKibRK3nUyRDLSXxMkU9PnFNaPNX59VPgyj4\r\nGB1CFSToldJVPF4pzh7p36uGXZVxs8m3LFD4Ol8mhi7jkxDZjqFN46gzR0r23Py6\r\ndol9vfawGIoUwp9LvL0S7MvdRY0oazLXwClLP4OQ17zpSMAiCj7fgNT661JamPGj\r\nt5O7Zn2wA7I4ddDS\/HDTWCu98Zwc9fHIpsJPgCZ9awoqxi4Mnf7Pk9g5nnXhszGC\r\ncxxIASQKM+GhdzoRxKknax2RzUCwCzcPRtCj8AQT\/x\/mqN3PfRmlnFBNACUw9bpZ\r\nSOoNq2pCF9igftDWpSIXQ38pVpKLWowjjg3DVRmVKBgivHnUnVLyzYBahHPj0vaz\r\ntFtUFRaqXDnt+4qyUGyrT5h5pjZaTcHIcSB4PiarYwdVvgslgwnQzOUcGAzRWBD4\r\n6jV2brP5vFY3g6iPAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBACTY3CCHC+Z28gCf\r\nFWGKQ3wAKs+k4+0yoti0qm2EKX7rSGQ0PHSas6uW79WstC4Rj+DYkDtIhGMSg8FS\r\nHVGZHGBCc0HwdX+BOAt3zi4p7Sf3oQef70\/4imPoKxbAVCpd\/cveVcFyDC19j1yB\r\nBapwu87oh+muoeaZxOlqQI4UxjBlR\/uRSMhOn2UGauIr3dWJgAF4pGt7TtIzt+1v\r\n0uA6FtN1Y4R5O8AaJPh1bIG0CVvFBE58esGzjEYLhOydgKFnEP94kVPgJD5ds9C3\r\npPhEpo1dRpiXaF7WGIV1X6DI\/ipWvfrF7CEy6I\/kP1InY\/vMDjQjeDnJ\/VrXIWXO\r\nyZvHXVaN\/m+1RlETsH7YO\/QmxRue9ZHN3gvvWtmpCeA95sfpepOk7UcHxHZYyQbF\r\n49\/au8j+5tsr4A83xzsT1JbcKRxkAaQ7WDJpOnE5O1+H0fB+BaLakTg6XX9d4Fo7\r\n7Gin7hVWX7pL+JIyxMzME3LhfI61+CRcqZQIrpyaafUziPQbWIPfEs7h8tCOWyvW\r\nUO8ZLervYCB3j44ivkrxPlcBklDCqqKKBzDP9dYOtS\/P4RB1NkHA9+NTvmBpTonS\r\nSFXdg9fFMD7VfjDE3Vnk+8DWkVH5wBYowTAD7w9Wuzr7DumiAULexnP\/Y7xwxLv7\r\n4B+pXTAcRK0zECDEaX3npS8xWzrB\r\n-----END CERTIFICATE-----" }'; $this->fileAccessHelper - ->expects($this->at(0)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json' - ) - ->willReturn($signatureDataFile); - $this->fileAccessHelper - ->expects($this->at(1)) - ->method('file_get_contents') - ->with( - \OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt' - ) - ->willReturn(file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt')); + ->expects($this->exactly(2)) + ->method('file_get_contents') + ->withConsecutive( + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//core/signature.json'], + [\OC::$SERVERROOT . '/tests/data/integritycheck/app//resources/codesigning/root.crt'], + )->willReturnOnConsecutiveCalls( + $signatureDataFile, + file_get_contents(__DIR__ .'/../../data/integritycheck/root.crt') + ); $expected = [ 'EXCEPTION' => [ @@ -1299,10 +1036,10 @@ class CheckerTest extends TestCase { ->getMock(); $this->checker - ->expects($this->at(0)) + ->expects($this->once()) ->method('verifyCoreSignature'); $this->appLocator - ->expects($this->at(0)) + ->expects($this->once()) ->method('getAllApps') ->willReturn([ 'files', @@ -1311,57 +1048,47 @@ class CheckerTest extends TestCase { 'dav', ]); $this->appManager - ->expects($this->at(0)) + ->expects($this->exactly(4)) ->method('isShipped') - ->with('files') - ->willReturn(true); + ->withConsecutive( + ['files'], + ['calendar'], + ['contacts'], + ['dav'], + )->willReturnOnConsecutiveCalls( + true, + false, + false, + true, + ); $this->checker - ->expects($this->at(1)) + ->expects($this->exactly(3)) ->method('verifyAppSignature') - ->with('files'); - $this->appManager - ->expects($this->at(1)) - ->method('isShipped') - ->with('calendar') - ->willReturn(false); + ->withConsecutive( + ['files'], + ['calendar'], + ['dav'], + ); $this->appLocator - ->expects($this->at(1)) + ->expects($this->exactly(2)) ->method('getAppPath') - ->with('calendar') - ->willReturn('/apps/calendar'); + ->withConsecutive( + ['calendar'], + ['contacts'], + )->willReturnOnConsecutiveCalls( + '/apps/calendar', + '/apps/contacts', + ); $this->fileAccessHelper - ->expects($this->at(0)) + ->expects($this->exactly(2)) ->method('file_exists') - ->with('/apps/calendar/appinfo/signature.json') - ->willReturn(true); - $this->checker - ->expects($this->at(2)) - ->method('verifyAppSignature') - ->with('calendar'); - $this->appManager - ->expects($this->at(2)) - ->method('isShipped') - ->with('contacts') - ->willReturn(false); - $this->appLocator - ->expects($this->at(2)) - ->method('getAppPath') - ->with('contacts') - ->willReturn('/apps/contacts'); - $this->fileAccessHelper - ->expects($this->at(1)) - ->method('file_exists') - ->with('/apps/contacts/appinfo/signature.json') - ->willReturn(false); - $this->appManager - ->expects($this->at(3)) - ->method('isShipped') - ->with('dav') - ->willReturn(true); - $this->checker - ->expects($this->at(3)) - ->method('verifyAppSignature') - ->with('dav'); + ->withConsecutive( + ['/apps/calendar/appinfo/signature.json'], + ['/apps/contacts/appinfo/signature.json'], + )->willReturnOnConsecutiveCalls( + true, + false, + ); $this->config ->expects($this->once()) ->method('deleteAppValue') diff --git a/tests/lib/L10N/FactoryTest.php b/tests/lib/L10N/FactoryTest.php index a2c1e8b5261..faf9dff48cc 100644 --- a/tests/lib/L10N/FactoryTest.php +++ b/tests/lib/L10N/FactoryTest.php @@ -105,20 +105,26 @@ class FactoryTest extends TestCase { public function testFindLanguageWithNotExistingRequestLanguageAndExistingStoredUserLanguage(): void { $factory = $this->getFactory(['languageExists']); $this->invokePrivate($factory, 'requestLanguage', ['de']); - $factory->expects(self::at(0)) + $factory->expects($this->exactly(2)) ->method('languageExists') - ->with('MyApp', 'de') - ->willReturn(false); + ->withConsecutive( + ['MyApp', 'de'], + ['MyApp', 'jp'], + ) + ->willReturnOnConsecutiveCalls( + false, + true, + ); $this->config - ->expects(self::at(0)) + ->expects($this->exactly(2)) ->method('getSystemValue') - ->with('force_language', false) - ->willReturn(false); - $this->config - ->expects(self::at(1)) - ->method('getSystemValue') - ->with('installed', false) - ->willReturn(true); + ->withConsecutive( + ['force_language', false], + ['installed', false], + )->willReturnOnConsecutiveCalls( + false, + true, + ); $user = $this->getMockBuilder(IUser::class) ->getMock(); $user->expects(self::once()) @@ -133,10 +139,6 @@ class FactoryTest extends TestCase { ->method('getUserValue') ->with('MyUserUid', 'core', 'lang', null) ->willReturn('jp'); - $factory->expects(self::at(1)) - ->method('languageExists') - ->with('MyApp', 'jp') - ->willReturn(true); self::assertSame('jp', $factory->findLanguage('MyApp')); } diff --git a/tests/lib/Log/ExceptionSerializerTest.php b/tests/lib/Log/ExceptionSerializerTest.php new file mode 100644 index 00000000000..209214a6832 --- /dev/null +++ b/tests/lib/Log/ExceptionSerializerTest.php @@ -0,0 +1,84 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2021 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +namespace lib\Log; + +use OC\Log\ExceptionSerializer; +use OC\SystemConfig; +use Test\TestCase; + +class ExceptionSerializerTest extends TestCase { + private ExceptionSerializer $serializer; + + public function setUp(): void { + parent::setUp(); + + $config = $this->createMock(SystemConfig::class); + $this->serializer = new ExceptionSerializer($config); + } + + private function emit($arguments) { + \call_user_func_array([$this, 'bind'], $arguments); + } + + private function bind(array &$myValues): void { + throw new \Exception('my exception'); + } + + private function customMagicAuthThing(string $login, string $parole): void { + throw new \Exception('expected custom auth exception'); + } + + /** + * this test ensures that the serializer does not overwrite referenced + * variables. It is crafted after a scenario we experienced: the DAV server + * emitting the "validateTokens" event, of which later on a handled + * exception was passed to the logger. The token was replaced, the original + * variable overwritten. + */ + public function testSerializer() { + try { + $secret = ['Secret']; + $this->emit([&$secret]); + } catch (\Exception $e) { + $serializedData = $this->serializer->serializeException($e); + $this->assertSame(['Secret'], $secret); + $this->assertSame(ExceptionSerializer::SENSITIVE_VALUE_PLACEHOLDER, $serializedData['Trace'][0]['args'][0]); + } + } + + public function testSerializerWithRegisteredMethods() { + $this->serializer->enlistSensitiveMethods(self::class, ['customMagicAuthThing']); + try { + $this->customMagicAuthThing('u57474', 'Secret'); + } catch (\Exception $e) { + $serializedData = $this->serializer->serializeException($e); + $this->assertSame('customMagicAuthThing', $serializedData['Trace'][0]['function']); + $this->assertSame(ExceptionSerializer::SENSITIVE_VALUE_PLACEHOLDER, $serializedData['Trace'][0]['args'][0]); + $this->assertFalse(isset($serializedData['Trace'][0]['args'][1])); + } + } +} diff --git a/tests/lib/Log/FileTest.php b/tests/lib/Log/FileTest.php index 937b3c75448..703c4280f24 100644 --- a/tests/lib/Log/FileTest.php +++ b/tests/lib/Log/FileTest.php @@ -1,6 +1,8 @@ <?php /** * + * @author Thomas Citharel <nextcloud@tcit.fr> + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE * License as published by the Free Software Foundation; either @@ -18,6 +20,7 @@ namespace Test\Log; use OC\Log\File; +use OCP\IConfig; use OCP\ILogger; use Test\TestCase; @@ -36,7 +39,7 @@ class FileTest extends TestCase { $config = \OC::$server->getSystemConfig(); $this->restore_logfile = $config->getValue("logfile"); $this->restore_logdateformat = $config->getValue('logdateformat'); - + $config->setValue("logfile", $config->getValue('datadirectory') . "/logtest.log"); $this->logFile = new File($config->getValue('datadirectory') . '/logtest.log', '', $config); } @@ -55,7 +58,28 @@ class FileTest extends TestCase { $this->logFile = new File($this->restore_logfile, '', $config); parent::tearDown(); } - + + public function testLogging() { + $config = \OC::$server->get(IConfig::class); + # delete old logfile + unlink($config->getSystemValue('logfile')); + + # set format & write log line + $config->setSystemValue('logdateformat', 'u'); + $this->logFile->write('code', ['something' => 'extra', 'message' => 'Testing logging'], ILogger::ERROR); + + # read log line + $handle = @fopen($config->getSystemValue('logfile'), 'r'); + $line = fread($handle, 1000); + fclose($handle); + + # check log has data content + $values = (array) json_decode($line, true); + $this->assertArrayNotHasKey('message', $values['data']); + $this->assertEquals('extra', $values['data']['something']); + $this->assertEquals('Testing logging', $values['message']); + } + public function testMicrosecondsLogTimestamp() { $config = \OC::$server->getConfig(); # delete old logfile @@ -69,7 +93,7 @@ class FileTest extends TestCase { $handle = @fopen($config->getSystemValue('logfile'), 'r'); $line = fread($handle, 1000); fclose($handle); - + # check timestamp has microseconds part $values = (array) json_decode($line); $microseconds = $values['time']; diff --git a/tests/lib/LoggerTest.php b/tests/lib/LoggerTest.php index 9b44fe198e2..bec2119a8ad 100644 --- a/tests/lib/LoggerTest.php +++ b/tests/lib/LoggerTest.php @@ -1,6 +1,9 @@ <?php /** * Copyright (c) 2014 Thomas Müller <thomas.mueller@tmit.eu> + * + * @author Thomas Citharel <nextcloud@tcit.fr> + * * This file is licensed under the Affero General Public License version 3 or * later. * See the COPYING-README file. @@ -9,29 +12,32 @@ namespace Test; use OC\Log; +use OC\SystemConfig; use OCP\ILogger; use OCP\Log\IWriter; +use OCP\Support\CrashReport\IRegistry; +use PHPUnit\Framework\MockObject\MockObject; class LoggerTest extends TestCase implements IWriter { - /** @var \OC\SystemConfig|\PHPUnit\Framework\MockObject\MockObject */ + /** @var SystemConfig|MockObject */ private $config; - /** @var \OCP\Support\CrashReport\IRegistry|\PHPUnit\Framework\MockObject\MockObject */ + /** @var IRegistry|MockObject */ private $registry; - /** @var \OCP\ILogger */ + /** @var ILogger */ private $logger; /** @var array */ - private $logs = []; + private array $logs = []; protected function setUp(): void { parent::setUp(); $this->logs = []; - $this->config = $this->createMock(\OC\SystemConfig::class); - $this->registry = $this->createMock(\OCP\Support\CrashReport\IRegistry::class); + $this->config = $this->createMock(SystemConfig::class); + $this->registry = $this->createMock(IRegistry::class); $this->logger = new Log($this, $this->config, null, $this->registry); } @@ -63,12 +69,23 @@ class LoggerTest extends TestCase implements IWriter { $this->assertEquals($expected, $this->getLogs()); } - private function getLogs() { + public function testLoggingWithDataArray(): void { + $writerMock = $this->createMock(IWriter::class); + $logFile = new Log($writerMock, $this->config); + $writerMock->expects($this->once())->method('write')->with('no app in context', ['something' => 'extra', 'message' => 'Testing logging with john']); + $logFile->error('Testing logging with {user}', ['something' => 'extra', 'user' => 'john']); + } + + private function getLogs(): array { return $this->logs; } public function write(string $app, $message, int $level) { - $this->logs[] = "$level $message"; + $textMessage = $message; + if (is_array($message)) { + $textMessage = $message['message']; + } + $this->logs[] = $level . " " . $textMessage; } public function userAndPasswordData(): array { diff --git a/tests/lib/Metadata/FileMetadataMapperTest.php b/tests/lib/Metadata/FileMetadataMapperTest.php index 8e385351be2..1a005f24b8a 100644 --- a/tests/lib/Metadata/FileMetadataMapperTest.php +++ b/tests/lib/Metadata/FileMetadataMapperTest.php @@ -24,6 +24,7 @@ namespace Test\Metadata; use OC\Metadata\FileMetadataMapper; use OC\Metadata\FileMetadata; +use PHPUnit\Framework\MockObject\MockObject; /** * @group DB @@ -33,9 +34,12 @@ class FileMetadataMapperTest extends \Test\TestCase { /** @var IDBConnection */ protected $connection; - /** @var SystemConfig|\PHPUnit\Framework\MockObject\MockObject */ + /** @var SystemConfig|MockObject */ protected $config; + /** @var FileMetadataMapper|MockObject */ + protected $mapper; + protected function setUp(): void { parent::setUp(); diff --git a/tests/lib/Preview/GeneratorTest.php b/tests/lib/Preview/GeneratorTest.php index 43f5c1e0d36..1e38afd7744 100644 --- a/tests/lib/Preview/GeneratorTest.php +++ b/tests/lib/Preview/GeneratorTest.php @@ -95,6 +95,7 @@ class GeneratorTest extends \Test\TestCase { $maxPreview = $this->createMock(ISimpleFile::class); $maxPreview->method('getName') ->willReturn('1000-1000-max.png'); + $maxPreview->method('getSize')->willReturn(1000); $maxPreview->method('getMimeType') ->willReturn('image/png'); @@ -102,6 +103,7 @@ class GeneratorTest extends \Test\TestCase { ->willReturn([$maxPreview]); $previewFile = $this->createMock(ISimpleFile::class); + $previewFile->method('getSize')->willReturn(1000); $previewFolder->method('getFile') ->with($this->equalTo('256-256.png')) @@ -203,8 +205,10 @@ class GeneratorTest extends \Test\TestCase { $maxPreview = $this->createMock(ISimpleFile::class); $maxPreview->method('getName')->willReturn('2048-2048-max.png'); $maxPreview->method('getMimeType')->willReturn('image/png'); + $maxPreview->method('getSize')->willReturn(1000); $previewFile = $this->createMock(ISimpleFile::class); + $previewFile->method('getSize')->willReturn(1000); $previewFolder->method('getDirectoryListing') ->willReturn([]); @@ -313,6 +317,7 @@ class GeneratorTest extends \Test\TestCase { $maxPreview = $this->createMock(ISimpleFile::class); $maxPreview->method('getName') ->willReturn('2048-2048-max.png'); + $maxPreview->method('getSize')->willReturn(1000); $maxPreview->method('getMimeType') ->willReturn('image/png'); @@ -320,6 +325,7 @@ class GeneratorTest extends \Test\TestCase { ->willReturn([$maxPreview]); $preview = $this->createMock(ISimpleFile::class); + $preview->method('getSize')->willReturn(1000); $previewFolder->method('getFile') ->with($this->equalTo('1024-512-crop.png')) ->willReturn($preview); @@ -471,6 +477,7 @@ class GeneratorTest extends \Test\TestCase { ->willReturn($maxX . '-' . $maxY . '-max.png'); $maxPreview->method('getMimeType') ->willReturn('image/png'); + $maxPreview->method('getSize')->willReturn(1000); $previewFolder->method('getDirectoryListing') ->willReturn([$maxPreview]); @@ -490,6 +497,7 @@ class GeneratorTest extends \Test\TestCase { ->willReturn($image); $preview = $this->createMock(ISimpleFile::class); + $preview->method('getSize')->willReturn(1000); $previewFolder->method('newFile') ->with($this->equalTo($filename)) ->willReturn($preview); diff --git a/tests/lib/Repair/RepairMimeTypesTest.php b/tests/lib/Repair/RepairMimeTypesTest.php index 26a52459c24..53c8e53d486 100644 --- a/tests/lib/Repair/RepairMimeTypesTest.php +++ b/tests/lib/Repair/RepairMimeTypesTest.php @@ -36,7 +36,6 @@ class RepairMimeTypesTest extends \Test\TestCase { protected function setUp(): void { parent::setUp(); - $this->savedMimetypeLoader = \OC::$server->getMimeTypeLoader(); $this->mimetypeLoader = \OC::$server->getMimeTypeLoader(); /** @var IConfig | \PHPUnit\Framework\MockObject\MockObject $config */ diff --git a/tests/lib/Settings/ManagerTest.php b/tests/lib/Settings/ManagerTest.php index 96711e75cab..29ae33c3c93 100644 --- a/tests/lib/Settings/ManagerTest.php +++ b/tests/lib/Settings/ManagerTest.php @@ -21,7 +21,7 @@ * */ -namespace OCA\Settings\Tests\AppInfo; +namespace OC\Settings\Tests\AppInfo; use OC\Settings\AuthorizedGroupMapper; use OC\Settings\Manager; @@ -82,16 +82,26 @@ class ManagerTest extends TestCase { public function testGetAdminSections() { $this->manager->registerSection('admin', \OCA\WorkflowEngine\Settings\Section::class); + $section = \OC::$server->query(\OCA\WorkflowEngine\Settings\Section::class); + $this->container->method('get') + ->with(\OCA\WorkflowEngine\Settings\Section::class) + ->willReturn($section); + $this->assertEquals([ - 55 => [\OC::$server->query(\OCA\WorkflowEngine\Settings\Section::class)], + 55 => [$section], ], $this->manager->getAdminSections()); } public function testGetPersonalSections() { $this->manager->registerSection('personal', \OCA\WorkflowEngine\Settings\Section::class); + $section = \OC::$server->query(\OCA\WorkflowEngine\Settings\Section::class); + $this->container->method('get') + ->with(\OCA\WorkflowEngine\Settings\Section::class) + ->willReturn($section); + $this->assertEquals([ - 55 => [\OC::$server->query(\OCA\WorkflowEngine\Settings\Section::class)], + 55 => [$section], ], $this->manager->getPersonalSections()); } @@ -181,14 +191,16 @@ class ManagerTest extends TestCase { $this->manager->registerSetting('personal', 'section1'); $this->manager->registerSetting('personal', 'section2'); - $this->container->expects($this->at(0)) + $this->container->expects($this->exactly(2)) ->method('get') - ->with('section1') - ->willReturn($section); - $this->container->expects($this->at(1)) - ->method('get') - ->with('section2') - ->willReturn($section2); + ->withConsecutive( + ['section1'], + ['section2'] + ) + ->willReturnMap([ + ['section1', $section], + ['section2', $section2], + ]); $settings = $this->manager->getPersonalSettings('security'); @@ -212,12 +224,18 @@ class ManagerTest extends TestCase { $this->manager->registerSection('personal', \OCA\WorkflowEngine\Settings\Section::class); $this->manager->registerSection('admin', \OCA\WorkflowEngine\Settings\Section::class); + + $section = \OC::$server->query(\OCA\WorkflowEngine\Settings\Section::class); + $this->container->method('get') + ->with(\OCA\WorkflowEngine\Settings\Section::class) + ->willReturn($section); + $this->assertEquals([ - 55 => [\OC::$server->query(\OCA\WorkflowEngine\Settings\Section::class)], + 55 => [$section], ], $this->manager->getPersonalSections()); $this->assertEquals([ - 55 => [\OC::$server->query(\OCA\WorkflowEngine\Settings\Section::class)], + 55 => [$section], ], $this->manager->getAdminSections()); } } diff --git a/tests/lib/Share20/DefaultShareProviderTest.php b/tests/lib/Share20/DefaultShareProviderTest.php index 03e1bdb4346..ed2bc2a4eda 100644 --- a/tests/lib/Share20/DefaultShareProviderTest.php +++ b/tests/lib/Share20/DefaultShareProviderTest.php @@ -23,6 +23,7 @@ namespace Test\Share20; use OC\Share20\DefaultShareProvider; +use OC\Share20\ShareAttributes; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Defaults; use OCP\Files\File; @@ -703,6 +704,11 @@ class DefaultShareProviderTest extends \Test\TestCase { $share->setSharedWithDisplayName('Displayed Name'); $share->setSharedWithAvatar('/path/to/image.svg'); $share->setPermissions(1); + + $attrs = new ShareAttributes(); + $attrs->setAttribute('permissions', 'download', true); + $share->setAttributes($attrs); + $share->setTarget('/target'); $share2 = $this->provider->create($share); @@ -723,6 +729,17 @@ class DefaultShareProviderTest extends \Test\TestCase { $this->assertSame('/path/to/image.svg', $share->getSharedWithAvatar()); $this->assertSame(null, $share2->getSharedWithDisplayName()); $this->assertSame(null, $share2->getSharedWithAvatar()); + + $this->assertSame( + [ + [ + 'scope' => 'permissions', + 'key' => 'download', + 'enabled' => true + ] + ], + $share->getAttributes()->toArray() + ); } public function testCreateGroupShare() { @@ -760,6 +777,9 @@ class DefaultShareProviderTest extends \Test\TestCase { $share->setSharedWithDisplayName('Displayed Name'); $share->setSharedWithAvatar('/path/to/image.svg'); $share->setTarget('/target'); + $attrs = new ShareAttributes(); + $attrs->setAttribute('permissions', 'download', true); + $share->setAttributes($attrs); $share2 = $this->provider->create($share); @@ -779,6 +799,17 @@ class DefaultShareProviderTest extends \Test\TestCase { $this->assertSame('/path/to/image.svg', $share->getSharedWithAvatar()); $this->assertSame(null, $share2->getSharedWithDisplayName()); $this->assertSame(null, $share2->getSharedWithAvatar()); + + $this->assertSame( + [ + [ + 'scope' => 'permissions', + 'key' => 'download', + 'enabled' => true + ] + ], + $share->getAttributes()->toArray() + ); } public function testCreateLinkShare() { diff --git a/tests/lib/Share20/ManagerTest.php b/tests/lib/Share20/ManagerTest.php index 2ed99519df6..4e613d1cf5c 100644 --- a/tests/lib/Share20/ManagerTest.php +++ b/tests/lib/Share20/ManagerTest.php @@ -593,7 +593,7 @@ class ManagerTest extends \Test\TestCase { } public function createShare($id, $type, $path, $sharedWith, $sharedBy, $shareOwner, - $permissions, $expireDate = null, $password = null) { + $permissions, $expireDate = null, $password = null, $attributes = null) { $share = $this->createMock(IShare::class); $share->method('getShareType')->willReturn($type); @@ -602,6 +602,7 @@ class ManagerTest extends \Test\TestCase { $share->method('getShareOwner')->willReturn($shareOwner); $share->method('getNode')->willReturn($path); $share->method('getPermissions')->willReturn($permissions); + $share->method('getAttributes')->willReturn($attributes); $share->method('getExpirationDate')->willReturn($expireDate); $share->method('getPassword')->willReturn($password); @@ -1914,13 +1915,31 @@ class ManagerTest extends \Test\TestCase { } - public function testLinkCreateChecksNoPublicUpload() { + public function testFileLinkCreateChecksNoPublicUpload() { + $share = $this->manager->newShare(); + + $share->setPermissions(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE); + $share->setNodeType('file'); + + $this->config + ->method('getAppValue') + ->willReturnMap([ + ['core', 'shareapi_allow_links', 'yes', 'yes'], + ['core', 'shareapi_allow_public_upload', 'yes', 'no'] + ]); + + self::invokePrivate($this->manager, 'linkCreateChecks', [$share]); + $this->addToAssertionCount(1); + } + + public function testFolderLinkCreateChecksNoPublicUpload() { $this->expectException(\Exception::class); $this->expectExceptionMessage('Public upload is not allowed'); $share = $this->manager->newShare(); $share->setPermissions(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE); + $share->setNodeType('folder'); $this->config ->method('getAppValue') @@ -1936,6 +1955,9 @@ class ManagerTest extends \Test\TestCase { $share = $this->manager->newShare(); $share->setPermissions(\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE); + $share->setSharedWith('sharedWith'); + $folder = $this->createMock(\OC\Files\Node\Folder::class); + $share->setNode($folder); $this->config ->method('getAppValue') @@ -1952,6 +1974,9 @@ class ManagerTest extends \Test\TestCase { $share = $this->manager->newShare(); $share->setPermissions(\OCP\Constants::PERMISSION_READ); + $share->setSharedWith('sharedWith'); + $folder = $this->createMock(\OC\Files\Node\Folder::class); + $share->setNode($folder); $this->config ->method('getAppValue') @@ -2946,6 +2971,9 @@ class ManagerTest extends \Test\TestCase { $share = $this->manager->newShare(); $share->setShareType(IShare::TYPE_LINK) ->setPermissions(\OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE); + $share->setSharedWith('sharedWith'); + $folder = $this->createMock(\OC\Files\Node\Folder::class); + $share->setNode($folder); $this->config ->expects($this->at(1)) @@ -3039,6 +3067,8 @@ class ManagerTest extends \Test\TestCase { $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare); $share = $this->manager->newShare(); + $attrs = $this->manager->newShare()->newAttributes(); + $attrs->setAttribute('app1', 'perm1', true); $share->setProviderId('foo') ->setId('42') ->setShareType(IShare::TYPE_USER); @@ -3129,6 +3159,8 @@ class ManagerTest extends \Test\TestCase { $manager->expects($this->once())->method('getShareById')->with('foo:42')->willReturn($originalShare); $share = $this->manager->newShare(); + $attrs = $this->manager->newShare()->newAttributes(); + $attrs->setAttribute('app1', 'perm1', true); $share->setProviderId('foo') ->setId('42') ->setShareType(IShare::TYPE_USER) @@ -3136,6 +3168,7 @@ class ManagerTest extends \Test\TestCase { ->setShareOwner('newUser') ->setSharedBy('sharer') ->setPermissions(31) + ->setAttributes($attrs) ->setNode($node); $this->defaultProvider->expects($this->once()) @@ -3160,6 +3193,7 @@ class ManagerTest extends \Test\TestCase { 'uidOwner' => 'sharer', 'permissions' => 31, 'path' => '/myPath', + 'attributes' => $attrs->toArray(), ]); $manager->updateShare($share); diff --git a/tests/lib/Share20/ShareByMailProviderTest.php b/tests/lib/Share20/ShareByMailProviderTest.php new file mode 100644 index 00000000000..3558be93a8b --- /dev/null +++ b/tests/lib/Share20/ShareByMailProviderTest.php @@ -0,0 +1,312 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright Copyright (c) 2022 Richard Steinmetz <richard@steinmetz.cloud> + * + * @author Richard Steinmetz <richard@steinmetz.cloud> + * + * @license AGPL-3.0-or-later + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see <http://www.gnu.org/licenses/> + * + */ + +namespace Test\Share20; + +use OC\Files\Node\Node; +use OCA\ShareByMail\Settings\SettingsManager; +use OCA\ShareByMail\ShareByMailProvider; +use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\Defaults; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\IRootFolder; +use OCP\IConfig; +use OCP\IDBConnection; +use OCP\IL10N; +use OCP\ILogger; +use OCP\IURLGenerator; +use OCP\IUserManager; +use OCP\Mail\IMailer; +use OCP\Security\IHasher; +use OCP\Security\ISecureRandom; +use OCP\Share\IShare; +use PHPUnit\Framework\MockObject\MockObject; +use Test\TestCase; + +/** + * Class ShareByMailProviderTest + * + * @package Test\Share20 + * @group DB + */ +class ShareByMailProviderTest extends TestCase { + + /** @var IDBConnection */ + protected $dbConn; + + /** @var IUserManager | \PHPUnit\Framework\MockObject\MockObject */ + protected $userManager; + + /** @var IRootFolder | \PHPUnit\Framework\MockObject\MockObject */ + protected $rootFolder; + + /** @var ShareByMailProvider */ + protected $provider; + + /** @var \PHPUnit\Framework\MockObject\MockObject|IMailer */ + protected $mailer; + + /** @var \PHPUnit\Framework\MockObject\MockObject|IL10N */ + protected $l10n; + + /** @var \PHPUnit\Framework\MockObject\MockObject|Defaults */ + protected $defaults; + + /** @var \PHPUnit\Framework\MockObject\MockObject|IURLGenerator */ + protected $urlGenerator; + + /** @var IConfig|MockObject */ + protected $config; + + /** @var ILogger|MockObject */ + private $logger; + + /** @var IHasher|MockObject */ + private $hasher; + + /** @var \OCP\Activity\IManager|MockObject */ + private $activityManager; + + /** @var IEventDispatcher|MockObject */ + private $eventDispatcher; + + /** @var \OCP\Share\IManager|MockObject */ + private $shareManager; + + /** @var ISecureRandom|MockObject */ + private $secureRandom; + + /** @var SettingsManager|MockObject */ + private $settingsManager; + + protected function setUp(): void { + $this->dbConn = \OC::$server->getDatabaseConnection(); + $this->userManager = $this->createMock(IUserManager::class); + $this->rootFolder = $this->createMock(IRootFolder::class); + $this->mailer = $this->createMock(IMailer::class); + $this->l10n = $this->createMock(IL10N::class); + $this->defaults = $this->getMockBuilder(Defaults::class)->disableOriginalConstructor()->getMock(); + $this->urlGenerator = $this->createMock(IURLGenerator::class); + $this->logger = $this->createMock(ILogger::class); + $this->activityManager = $this->createMock(\OCP\Activity\IManager::class); + $this->settingsManager = $this->createMock(SettingsManager::class); + $this->hasher = $this->createMock(IHasher::class); + $this->eventDispatcher = $this->createMock(IEventDispatcher::class); + $this->shareManager = $this->createMock(\OCP\Share\IManager::class); + $this->secureRandom = $this->createMock(ISecureRandom::class); + $this->config = $this->createMock(IConfig::class); + + // Empty share table + $this->dbConn->getQueryBuilder()->delete('share')->execute(); + + $this->provider = new ShareByMailProvider( + $this->config, + $this->dbConn, + $this->secureRandom, + $this->userManager, + $this->rootFolder, + $this->l10n, + $this->logger, + $this->mailer, + $this->urlGenerator, + $this->activityManager, + $this->settingsManager, + $this->defaults, + $this->hasher, + $this->eventDispatcher, + $this->shareManager, + ); + } + + protected function tearDown(): void { + $this->dbConn->getQueryBuilder()->delete('share')->execute(); + $this->dbConn->getQueryBuilder()->delete('filecache')->execute(); + $this->dbConn->getQueryBuilder()->delete('storages')->execute(); + } + + /** + * @param int $shareType + * @param string $sharedWith + * @param string $sharedBy + * @param string $shareOwner + * @param string $itemType + * @param int $fileSource + * @param string $fileTarget + * @param int $permissions + * @param $token + * @param $expiration + * @param $parent + * @return int + * + * @throws \OCP\DB\Exception + */ + private function addShareToDB($shareType, $sharedWith, $sharedBy, $shareOwner, + $itemType, $fileSource, $fileTarget, $permissions, $token, $expiration, + $parent) { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('share'); + + if ($shareType) { + $qb->setValue('share_type', $qb->expr()->literal($shareType)); + } + if ($sharedWith) { + $qb->setValue('share_with', $qb->expr()->literal($sharedWith)); + } + if ($sharedBy) { + $qb->setValue('uid_initiator', $qb->expr()->literal($sharedBy)); + } + if ($shareOwner) { + $qb->setValue('uid_owner', $qb->expr()->literal($shareOwner)); + } + if ($itemType) { + $qb->setValue('item_type', $qb->expr()->literal($itemType)); + } + if ($fileSource) { + $qb->setValue('file_source', $qb->expr()->literal($fileSource)); + } + if ($fileTarget) { + $qb->setValue('file_target', $qb->expr()->literal($fileTarget)); + } + if ($permissions) { + $qb->setValue('permissions', $qb->expr()->literal($permissions)); + } + if ($token) { + $qb->setValue('token', $qb->expr()->literal($token)); + } + if ($expiration) { + $qb->setValue('expiration', $qb->createNamedParameter($expiration, IQueryBuilder::PARAM_DATE)); + } + if ($parent) { + $qb->setValue('parent', $qb->expr()->literal($parent)); + } + + $this->assertEquals(1, $qb->execute()); + return $qb->getLastInsertId(); + } + + public function testGetSharesByWithResharesAndNoNode() { + $this->addShareToDB( + IShare::TYPE_EMAIL, + 'external.one@domain.tld', + 'user1', + 'user1', + 'folder', + 42, + null, + 17, + 'foobar', + null, + null, + ); + $this->addShareToDB( + IShare::TYPE_EMAIL, + 'external.two@domain.tld', + 'user2', + 'user2', + 'folder', + 42, + null, + 17, + 'barfoo', + null, + null, + ); + + // Return own shares only if not asked for a specific node + /** @var IShare[] $actual */ + $actual = $this->provider->getSharesBy( + 'user1', + IShare::TYPE_EMAIL, + null, + true, + -1, + 0, + ); + + $this->assertCount(1, $actual); + + $this->assertEquals(IShare::TYPE_EMAIL, $actual[0]->getShareType()); + $this->assertEquals('user1', $actual[0]->getSharedBy()); + $this->assertEquals('user1', $actual[0]->getShareOwner()); + $this->assertEquals('external.one@domain.tld', $actual[0]->getSharedWith()); + } + + public function testGetSharesByWithResharesAndNode() { + $this->addShareToDB( + IShare::TYPE_EMAIL, + 'external.one@domain.tld', + 'user1', + 'user1', + 'folder', + 42, + null, + 17, + 'foobar', + null, + null, + ); + $this->addShareToDB( + IShare::TYPE_EMAIL, + 'external.two@domain.tld', + 'user2', + 'user2', + 'folder', + 42, + null, + 17, + 'barfoo', + null, + null, + ); + + $node = $this->createMock(Node::class); + $node->expects($this->once()) + ->method('getId') + ->willReturn(42); + + // Return all shares if asked for specific node + /** @var IShare[] $actual */ + $actual = $this->provider->getSharesBy( + 'user1', + IShare::TYPE_EMAIL, + $node, + true, + -1, + 0, + ); + + $this->assertCount(2, $actual); + + $this->assertEquals(IShare::TYPE_EMAIL, $actual[0]->getShareType()); + $this->assertEquals('user1', $actual[0]->getSharedBy()); + $this->assertEquals('user1', $actual[0]->getShareOwner()); + $this->assertEquals('external.one@domain.tld', $actual[0]->getSharedWith()); + + $this->assertEquals(IShare::TYPE_EMAIL, $actual[1]->getShareType()); + $this->assertEquals('user2', $actual[1]->getSharedBy()); + $this->assertEquals('user2', $actual[1]->getShareOwner()); + $this->assertEquals('external.two@domain.tld', $actual[1]->getSharedWith()); + } +} diff --git a/tests/lib/UrlGeneratorTest.php b/tests/lib/UrlGeneratorTest.php index 9e5795fc41e..7fdbb7fb37e 100644 --- a/tests/lib/UrlGeneratorTest.php +++ b/tests/lib/UrlGeneratorTest.php @@ -297,7 +297,7 @@ class UrlGeneratorTest extends \Test\TestCase { $this->assertEquals('http://localhost' . \OC::$WEBROOT . $expectedPath, $this->urlGenerator->linkToDefaultPageUrl()); } - public function provideDefaultApps() { + public function provideDefaultApps(): array { return [ // none specified, default to files [ @@ -321,4 +321,18 @@ class UrlGeneratorTest extends \Test\TestCase { ], ]; } + + public function imagePathProvider(): array { + return [ + ['core', 'favicon-mask.svg', \OC::$WEBROOT . '/core/img/favicon-mask.svg'], + ['files', 'external.svg', \OC::$WEBROOT . '/apps/files/img/external.svg'], + ]; + } + + /** + * @dataProvider imagePathProvider + */ + public function testImagePath(string $appName, string $file, string $result): void { + $this->assertSame($result, $this->urlGenerator->imagePath($appName, $file)); + } } diff --git a/tests/lib/User/ManagerTest.php b/tests/lib/User/ManagerTest.php index 26fc39a1e31..cef578e9555 100644 --- a/tests/lib/User/ManagerTest.php +++ b/tests/lib/User/ManagerTest.php @@ -608,7 +608,7 @@ class ManagerTest extends TestCase { public function testCountUsersOnlySeen() { $manager = \OC::$server->getUserManager(); // count other users in the db before adding our own - $countBefore = $manager->countUsers(true); + $countBefore = $manager->countSeenUsers(); //Add test users $user1 = $manager->createUser('testseencount1', 'testseencount1'); @@ -622,7 +622,7 @@ class ManagerTest extends TestCase { $user4 = $manager->createUser('testseencount4', 'testseencount4'); $user4->updateLastLoginTimestamp(); - $this->assertEquals($countBefore + 3, $manager->countUsers(true)); + $this->assertEquals($countBefore + 3, $manager->countSeenUsers()); //cleanup $user1->delete(); diff --git a/tests/lib/User/SessionTest.php b/tests/lib/User/SessionTest.php index 0e199e5d5b5..735a3b3d06a 100644 --- a/tests/lib/User/SessionTest.php +++ b/tests/lib/User/SessionTest.php @@ -43,6 +43,8 @@ use OC\Security\CSRF\CsrfTokenManager; class SessionTest extends \Test\TestCase { /** @var ITimeFactory|MockObject */ private $timeFactory; + /** @var IProvider|MockObject */ + private $tokenProvider; /** @var IConfig|MockObject */ private $config; /** @var Throttler|MockObject */ diff --git a/tests/lib/User/UserTest.php b/tests/lib/User/UserTest.php index 7fab7ececca..cc65fbf3356 100644 --- a/tests/lib/User/UserTest.php +++ b/tests/lib/User/UserTest.php @@ -16,6 +16,7 @@ use OC\User\User; use OCP\Comments\ICommentsManager; use OCP\Files\Storage\IStorageFactory; use OCP\IConfig; +use OCP\IURLGenerator; use OCP\IUser; use OCP\Notification\IManager as INotificationManager; use OCP\Notification\INotification; @@ -43,7 +44,7 @@ class UserTest extends TestCase { public function testDisplayName() { /** - * @var \OC\User\Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var \OC\User\Backend | MockObject $backend */ $backend = $this->createMock(\OC\User\Backend::class); $backend->expects($this->once()) @@ -65,7 +66,7 @@ class UserTest extends TestCase { */ public function testDisplayNameEmpty() { /** - * @var \OC\User\Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var \OC\User\Backend | MockObject $backend */ $backend = $this->createMock(\OC\User\Backend::class); $backend->expects($this->once()) @@ -84,7 +85,7 @@ class UserTest extends TestCase { public function testDisplayNameNotSupported() { /** - * @var \OC\User\Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var \OC\User\Backend | MockObject $backend */ $backend = $this->createMock(\OC\User\Backend::class); $backend->expects($this->never()) @@ -101,7 +102,7 @@ class UserTest extends TestCase { public function testSetPassword() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $backend->expects($this->once()) @@ -124,7 +125,7 @@ class UserTest extends TestCase { public function testSetPasswordNotSupported() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $backend->expects($this->never()) @@ -140,7 +141,7 @@ class UserTest extends TestCase { public function testChangeAvatarSupportedYes() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(AvatarUserDummy::class); $backend->expects($this->once()) @@ -164,7 +165,7 @@ class UserTest extends TestCase { public function testChangeAvatarSupportedNo() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(AvatarUserDummy::class); $backend->expects($this->once()) @@ -188,7 +189,7 @@ class UserTest extends TestCase { public function testChangeAvatarNotSupported() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(AvatarUserDummy::class); $backend->expects($this->never()) @@ -204,7 +205,7 @@ class UserTest extends TestCase { public function testDelete() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $backend->expects($this->once()) @@ -227,11 +228,11 @@ class UserTest extends TestCase { } /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); - $backend->expects($this->at(0)) + $backend->expects($this->once()) ->method('implementsActions') ->willReturnCallback(function ($actions) { if ($actions === \OC\User\Backend::GET_HOME) { @@ -244,12 +245,12 @@ class UserTest extends TestCase { // important: getHome MUST be called before deleteUser because // once the user is deleted, getHome implementations might not // return anything - $backend->expects($this->at(1)) + $backend->expects($this->once()) ->method('getHome') ->with($this->equalTo('foo')) ->willReturn('/home/foo'); - $backend->expects($this->at(2)) + $backend->expects($this->once()) ->method('deleteUser') ->with($this->equalTo('foo')); @@ -259,7 +260,7 @@ class UserTest extends TestCase { public function testGetHome() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $backend->expects($this->once()) @@ -290,7 +291,7 @@ class UserTest extends TestCase { public function testGetHomeNotSupported() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $backend->expects($this->never()) @@ -317,7 +318,7 @@ class UserTest extends TestCase { public function testCanChangePassword() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -337,7 +338,7 @@ class UserTest extends TestCase { public function testCanChangePasswordNotSupported() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -351,7 +352,7 @@ class UserTest extends TestCase { public function testCanChangeDisplayName() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -371,7 +372,7 @@ class UserTest extends TestCase { public function testCanChangeDisplayNameNotSupported() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -385,7 +386,7 @@ class UserTest extends TestCase { public function testSetDisplayNameSupported() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\OC\User\Database::class); @@ -414,7 +415,7 @@ class UserTest extends TestCase { */ public function testSetDisplayNameEmpty() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\OC\User\Database::class); @@ -435,7 +436,7 @@ class UserTest extends TestCase { public function testSetDisplayNameNotSupported() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\OC\User\Database::class); @@ -456,7 +457,7 @@ class UserTest extends TestCase { $test = $this; /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $backend->expects($this->once()) @@ -509,7 +510,7 @@ class UserTest extends TestCase { $test = $this; /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); $backend->expects($this->once()) @@ -587,26 +588,30 @@ class UserTest extends TestCase { $this->assertEquals($expectedHooks, $hooksCalled); } - public function testGetCloudId() { - /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend - */ + public function dataGetCloudId(): array { + return [ + ['https://localhost:8888/nextcloud', 'foo@localhost:8888/nextcloud'], + ['http://localhost:8888/nextcloud', 'foo@http://localhost:8888/nextcloud'], + ]; + } + + /** + * @dataProvider dataGetCloudId + */ + public function testGetCloudId(string $absoluteUrl, string $cloudId): void { + /** @var Backend|MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); - $urlGenerator = $this->getMockBuilder('\OC\URLGenerator') - ->setMethods(['getAbsoluteURL']) - ->disableOriginalConstructor()->getMock(); - $urlGenerator - ->expects($this->any()) - ->method('getAbsoluteURL') - ->withAnyParameters() - ->willReturn('http://localhost:8888/owncloud'); + $urlGenerator = $this->createMock(IURLGenerator::class); + $urlGenerator->method('getAbsoluteURL') + ->withAnyParameters() + ->willReturn($absoluteUrl); $user = new User('foo', $backend, $this->dispatcher, null, null, $urlGenerator); - $this->assertEquals('foo@localhost:8888/owncloud', $user->getCloudId()); + $this->assertEquals($cloudId, $user->getCloudId()); } public function testSetEMailAddressEmpty() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -642,7 +647,7 @@ class UserTest extends TestCase { public function testSetEMailAddress() { /** - * @var UserInterface | \PHPUnit\Framework\MockObject\MockObject $backend + * @var UserInterface | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -679,11 +684,11 @@ class UserTest extends TestCase { public function testSetEMailAddressNoChange() { /** - * @var UserInterface | \PHPUnit\Framework\MockObject\MockObject $backend + * @var UserInterface | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); - /** @var PublicEmitter|\PHPUnit\Framework\MockObject\MockObject $emitter */ + /** @var PublicEmitter|MockObject $emitter */ $emitter = $this->createMock(PublicEmitter::class); $emitter->expects($this->never()) ->method('emit'); @@ -704,7 +709,7 @@ class UserTest extends TestCase { public function testSetQuota() { /** - * @var UserInterface | \PHPUnit\Framework\MockObject\MockObject $backend + * @var UserInterface | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -741,11 +746,11 @@ class UserTest extends TestCase { public function testGetDefaultUnlimitedQuota() { /** - * @var UserInterface | \PHPUnit\Framework\MockObject\MockObject $backend + * @var UserInterface | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); - /** @var PublicEmitter|\PHPUnit\Framework\MockObject\MockObject $emitter */ + /** @var PublicEmitter|MockObject $emitter */ $emitter = $this->createMock(PublicEmitter::class); $emitter->expects($this->never()) ->method('emit'); @@ -772,11 +777,11 @@ class UserTest extends TestCase { public function testGetDefaultUnlimitedQuotaForbidden() { /** - * @var UserInterface | \PHPUnit\Framework\MockObject\MockObject $backend + * @var UserInterface | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); - /** @var PublicEmitter|\PHPUnit\Framework\MockObject\MockObject $emitter */ + /** @var PublicEmitter|MockObject $emitter */ $emitter = $this->createMock(PublicEmitter::class); $emitter->expects($this->never()) ->method('emit'); @@ -806,11 +811,11 @@ class UserTest extends TestCase { public function testSetQuotaAddressNoChange() { /** - * @var UserInterface | \PHPUnit\Framework\MockObject\MockObject $backend + * @var UserInterface | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); - /** @var PublicEmitter|\PHPUnit\Framework\MockObject\MockObject $emitter */ + /** @var PublicEmitter|MockObject $emitter */ $emitter = $this->createMock(PublicEmitter::class); $emitter->expects($this->never()) ->method('emit'); @@ -828,7 +833,7 @@ class UserTest extends TestCase { public function testGetLastLogin() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -848,7 +853,7 @@ class UserTest extends TestCase { public function testSetEnabled() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -868,7 +873,7 @@ class UserTest extends TestCase { public function testSetDisabled() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -908,7 +913,7 @@ class UserTest extends TestCase { public function testSetDisabledAlreadyDisabled() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); @@ -938,7 +943,7 @@ class UserTest extends TestCase { public function testGetEMailAddress() { /** - * @var Backend | \PHPUnit\Framework\MockObject\MockObject $backend + * @var Backend | MockObject $backend */ $backend = $this->createMock(\Test\Util\User\Dummy::class); |