diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 781e9da..2eb0371 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -9,7 +9,7 @@ jobs: strategy: fail-fast: false matrix: - php: [7.4, 8.0, 8.1, 8.2, 8.3] + php: [7.4, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5] steps: - name: Checkout diff --git a/composer.json b/composer.json index f7fdd08..a9b3610 100644 --- a/composer.json +++ b/composer.json @@ -23,8 +23,6 @@ "psr/http-server-middleware": "^1.0" }, "require-dev": { - "phpspec/prophecy": "^1.19", - "phpspec/prophecy-phpunit": "^2.2", "phpunit/phpunit": "^9.6", "squizlabs/php_codesniffer": "^3.10" }, @@ -37,5 +35,19 @@ "psr-4": { "Slim\\Csrf\\Tests\\": "tests" } + }, + "scripts": { + "sniffer:check": "phpcs --standard=phpcs.xml", + "sniffer:fix": "phpcbf --standard=phpcs.xml", + "test": "phpunit --do-not-cache-result --colors=always", + "check": [ + "@sniffer:check", + "@test:coverage" + ], + "test:coverage": [ + "@putenv XDEBUG_MODE=coverage", + "phpunit --do-not-cache-result --colors=always --coverage-clover build/coverage/clover.xml --coverage-html build/coverage --coverage-text" + ] } + } diff --git a/tests/GuardTest.php b/tests/GuardTest.php index 1e35dd4..af84fc1 100644 --- a/tests/GuardTest.php +++ b/tests/GuardTest.php @@ -12,8 +12,6 @@ use ArrayIterator; use PHPUnit\Framework\TestCase; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; use Psr\Http\Message\ResponseFactoryInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -21,6 +19,7 @@ use Psr\Http\Server\RequestHandlerInterface; use ReflectionException; use ReflectionMethod; +use ReflectionProperty; use RuntimeException; use Slim\Csrf\Guard; @@ -29,7 +28,15 @@ class GuardTest extends TestCase { - use ProphecyTrait; + protected function setAccessible(ReflectionMethod $property, bool $accessible = true): void + { + // only if PHP version < 8.1 + if (PHP_VERSION_ID >= 80100) { + return; + } + $property->setAccessible($accessible); + } + /** * Helper function to mask a token using private method {@link Guard::maskToken()} @@ -44,7 +51,7 @@ class GuardTest extends TestCase private function maskToken(Guard $middleware, string $token): string { $maskTokenMethod = new ReflectionMethod($middleware, 'maskToken'); - $maskTokenMethod->setAccessible(true); + $this->setAccessible($maskTokenMethod); return $maskTokenMethod->invoke($middleware, $token); } @@ -52,11 +59,11 @@ private function maskToken(Guard $middleware, string $token): string public function testStrengthLowerThan16ThrowsException() { $storage = []; - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); $this->expectException(RuntimeException::class); $this->expectExceptionMessage('CSRF middleware instantiation failed. Minimum strength is 16.'); - new Guard($responseFactoryProphecy->reveal(), 'test', $storage, null, 200, 15); + new Guard($responseFactory, 'test', $storage, null, 200, 15); } /** @@ -64,11 +71,11 @@ public function testStrengthLowerThan16ThrowsException() */ public function testSetStorageThrowsExceptionWhenFallingBackOnSessionThatHasNotBeenStarted() { - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Invalid CSRF storage.'); - new Guard($responseFactoryProphecy->reveal(), 'test'); + new Guard($responseFactory, 'test'); } /** @@ -77,117 +84,123 @@ public function testSetStorageThrowsExceptionWhenFallingBackOnSessionThatHasNotB public function testSetStorageSetsKeysOnSessionObjectWhenNotExist() { session_start(); - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - new Guard($responseFactoryProphecy->reveal(), 'test'); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + new Guard($responseFactory, 'test'); $this->assertArrayHasKey('test', $_SESSION); } public function testSetFailureHandler() { - $self = $this; - $storage = []; - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + $mw = new Guard($responseFactory, 'test', $storage); $called = 0; - $handler = function () use ($self, &$called) { + $handler = function () use (&$called) { $called++; - $responseProphecy = $self->prophesize(ResponseInterface::class); - return $responseProphecy->reveal(); + return $this->createMock(ResponseInterface::class); }; $mw->setFailureHandler($handler); - $requestProphecy = $this->prophesize(ServerRequestInterface::class); - $requestProphecy - ->getMethod() - ->willReturn('POST') - ->shouldBeCalledOnce(); + $request = $this->createMock(ServerRequestInterface::class); + $request + ->expects($this->once()) + ->method('getMethod') + ->willReturn('POST'); - $requestProphecy - ->withAttribute(Argument::type('string'), Argument::type('string')) - ->willReturn($requestProphecy->reveal()) - ->shouldBeCalledTimes(2); + $request + ->expects($this->exactly(2)) + ->method('withAttribute') + ->with($this->isType('string'), $this->isType('string')) + ->willReturn($request); - $requestProphecy - ->getParsedBody() - ->willReturn([]) - ->shouldBeCalledOnce(); + $request + ->expects($this->once()) + ->method('getParsedBody') + ->willReturn([]); - $requestProphecy - ->getHeader(Argument::type('string')) - ->willReturn([]) - ->shouldBeCalledTimes(2); + $request + ->expects($this->exactly(2)) + ->method('getHeader') + ->with($this->isType('string')) + ->willReturn([]); - $requestHandlerProphecy = $this->prophesize(RequestHandlerInterface::class); + $requestHandler = $this->createMock(RequestHandlerInterface::class); - $mw->process($requestProphecy->reveal(), $requestHandlerProphecy->reveal()); + $mw->process($request, $requestHandler); $this->assertEquals(1, $called); } public function testDefaultFailureHandler() { - $streamProphecy = $this->prophesize(StreamInterface::class); - $streamProphecy - ->write('Failed CSRF check!') - ->shouldBeCalledOnce(); - - $responseProphecy = $this->prophesize(ResponseInterface::class); - - $responseProphecy - ->getBody() - ->willReturn($streamProphecy->reveal()) - ->shouldBeCalledOnce(); - - $responseProphecy - ->withStatus(400) - ->willReturn($responseProphecy->reveal()) - ->shouldBeCalledOnce(); - - $responseProphecy - ->withHeader('Content-Type', 'text/plain') - ->willReturn($responseProphecy->reveal()) - ->shouldBeCalledOnce(); - - $responseProphecy - ->withBody($streamProphecy->reveal()) - ->willReturn($responseProphecy->reveal()) - ->shouldBeCalledOnce(); - - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - $responseFactoryProphecy - ->createResponse() - ->willReturn($responseProphecy->reveal()); + $stream = $this->createMock(StreamInterface::class); + $stream + ->expects($this->once()) + ->method('write') + ->with('Failed CSRF check!'); + + $response = $this->createMock(ResponseInterface::class); + + $response + ->expects($this->once()) + ->method('getBody') + ->willReturn($stream); + + $response + ->expects($this->once()) + ->method('withStatus') + ->with(400) + ->willReturn($response); + + $response + ->expects($this->once()) + ->method('withHeader') + ->with('Content-Type', 'text/plain') + ->willReturn($response); + + $response + ->expects($this->once()) + ->method('withBody') + ->with($stream) + ->willReturn($response); + + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + $responseFactory + ->expects($this->once()) + ->method('createResponse') + ->willReturn($response); $storage = []; - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage); - - $requestProphecy = $this->prophesize(ServerRequestInterface::class); - $requestProphecy - ->getMethod() - ->willReturn('POST') - ->shouldBeCalledOnce(); - - $requestProphecy - ->withAttribute(Argument::type('string'), Argument::type('string')) - ->willReturn($requestProphecy->reveal()) - ->shouldBeCalledTimes(2); - - $requestProphecy - ->getParsedBody() - ->willReturn([]) - ->shouldBeCalledOnce(); - - $requestProphecy - ->getHeader(Argument::type('string')) - ->willReturn([]) - ->shouldBeCalledTimes(2); - - $requestHandlerProphecy = $this->prophesize(RequestHandlerInterface::class); - - $response = $mw->process($requestProphecy->reveal(), $requestHandlerProphecy->reveal()); - $this->assertSame($response, $responseProphecy->reveal()); + $mw = new Guard($responseFactory, 'test', $storage); + + $request = $this->createMock(ServerRequestInterface::class); + $request + ->expects($this->once()) + ->method('getMethod') + ->willReturn('POST'); + + $request + ->expects($this->exactly(2)) + ->method('withAttribute') + ->with($this->isType('string'), $this->isType('string')) + ->willReturn($request); + + $request + ->expects($this->once()) + ->method('getParsedBody') + ->willReturn([]); + + $request + ->expects($this->exactly(2)) + ->method('getHeader') + ->with($this->isType('string')) + ->willReturn([]); + + $requestHandler = $this->createMock(RequestHandlerInterface::class); + + $actualResponse = $mw->process($request, $requestHandler); + $this->assertSame($actualResponse, $response); } public function testValidateToken() @@ -195,8 +208,8 @@ public function testValidateToken() $storage = [ 'test_name' => 'value' ]; - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + $mw = new Guard($responseFactory, 'test', $storage); $maskedToken = $this->maskToken($mw, 'value'); $this->assertTrue($mw->validateToken('test_name', $maskedToken)); @@ -212,8 +225,8 @@ public function testNotValidatingBadToken() $storage = [ 'test_name' => 'value' ]; - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + $mw = new Guard($responseFactory, 'test', $storage); $maskedToken = 'MY_BAD_BASE64???'; $this->assertFalse($mw->validateToken('test_name', $maskedToken), 'Token contains bad base64 characters'); @@ -227,14 +240,14 @@ public function testNotValidatingBadToken() public function testGetTokenNameAndValue() { $storage = []; - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + $mw = new Guard($responseFactory, 'test', $storage); $this->assertNull($mw->getTokenName()); $this->assertNull($mw->getTokenValue()); $loadLastKeyPairMethod = new ReflectionMethod($mw, 'loadLastKeyPair'); - $loadLastKeyPairMethod->setAccessible(true); + $this->setAccessible($loadLastKeyPairMethod); $loadLastKeyPairMethod->invoke($mw); $storage = [ @@ -246,7 +259,7 @@ public function testGetTokenNameAndValue() $this->assertEquals('test_name', $mw->getTokenName()); $unmaskTokenMethod = new ReflectionMethod($mw, 'unmaskToken'); - $unmaskTokenMethod->setAccessible(true); + $this->setAccessible($unmaskTokenMethod); $unmaskedToken = $unmaskTokenMethod->invoke($mw, $mw->getTokenValue()); $this->assertEquals('value', $unmaskedToken); } @@ -254,8 +267,8 @@ public function testGetTokenNameAndValue() public function testGetPersistentTokenMode() { $storage = []; - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage, null, 200, 16, true); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + $mw = new Guard($responseFactory, 'test', $storage, null, 200, 16, true); $this->assertTrue($mw->getPersistentTokenMode()); } @@ -263,8 +276,8 @@ public function testGetPersistentTokenMode() public function testGetTokenNameKeyAndValue() { $storage = []; - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + $mw = new Guard($responseFactory, 'test', $storage); $this->assertEquals('test_name', $mw->getTokenNameKey()); $this->assertEquals('test_value', $mw->getTokenValueKey()); @@ -275,11 +288,11 @@ public function testRemoveTokenFromStorage() $storage = [ 'test_name' => 'value', ]; - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + $mw = new Guard($responseFactory, 'test', $storage); $removeTokenFromStorageMethod = new ReflectionMethod($mw, 'removeTokenFromStorage'); - $removeTokenFromStorageMethod->setAccessible(true); + $this->setAccessible($removeTokenFromStorageMethod); $removeTokenFromStorageMethod->invoke($mw, 'test_name'); $this->assertArrayNotHasKey('test_name', $storage); @@ -291,11 +304,11 @@ public function testEnforceStorageLimitWithArray() 'test_name' => 'value', 'test_name2' => 'value2', ]; - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage, null, 1); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + $mw = new Guard($responseFactory, 'test', $storage, null, 1); $enforceStorageLimitMethod = new ReflectionMethod($mw, 'enforceStorageLimit'); - $enforceStorageLimitMethod->setAccessible(true); + $this->setAccessible($enforceStorageLimitMethod); $enforceStorageLimitMethod->invoke($mw); $this->assertArrayNotHasKey('test_name', $storage); @@ -308,11 +321,11 @@ public function testNotEnforceStorageLimitWithArrayWhenLimitIsZero() 'test_name' => 'value', 'test_name2' => 'value2', ]; - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage, null, 0); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + $mw = new Guard($responseFactory, 'test', $storage, null, 0); $enforceStorageLimitMethod = new ReflectionMethod($mw, 'enforceStorageLimit'); - $enforceStorageLimitMethod->setAccessible(true); + $this->setAccessible($enforceStorageLimitMethod); $enforceStorageLimitMethod->invoke($mw); $this->assertSame($initial_storage, $storage); @@ -324,11 +337,11 @@ public function testEnforceStorageLimitWithIterator() 'test_name' => 'value', 'test_name2' => 'value', ]); - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage, null, 1); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + $mw = new Guard($responseFactory, 'test', $storage, null, 1); $enforceStorageLimitMethod = new ReflectionMethod($mw, 'enforceStorageLimit'); - $enforceStorageLimitMethod->setAccessible(true); + $this->setAccessible($enforceStorageLimitMethod); $enforceStorageLimitMethod->invoke($mw); $this->assertArrayNotHasKey('test_name', $storage); @@ -341,38 +354,39 @@ public function testTokenIsRemovedFromStorageWhenPersistentModeIsOff() 'test_name' => 'test_value123', ]; - $responseProphecy = $this->prophesize(ResponseInterface::class) - ->willImplement(ResponseInterface::class); - - $requestHandlerProphecy = $this->prophesize(RequestHandlerInterface::class); - $requestHandlerProphecy - ->handle(Argument::type(ServerRequestInterface::class)) - ->willReturn($responseProphecy->reveal()) - ->shouldBeCalledOnce(); - - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage); - - $requestProphecy = $this->prophesize(ServerRequestInterface::class); - $requestProphecy - ->getMethod() - ->willReturn('POST') - ->shouldBeCalledOnce(); - $requestProphecy - ->withAttribute(Argument::type('string'), Argument::type('string')) - ->willReturn($requestProphecy->reveal()) - ->shouldBeCalledTimes(2); - $requestProphecy - ->getParsedBody() + $response = $this->createMock(ResponseInterface::class); + + $requestHandler = $this->createMock(RequestHandlerInterface::class); + $requestHandler + ->expects($this->once()) + ->method('handle') + ->with($this->isInstanceOf(ServerRequestInterface::class)) + ->willReturn($response); + + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + + $mw = new Guard($responseFactory, 'test', $storage); + + $request = $this->createMock(ServerRequestInterface::class); + $request + ->expects($this->once()) + ->method('getMethod') + ->willReturn('POST'); + $request + ->expects($this->exactly(2)) + ->method('withAttribute') + ->with($this->isType('string'), $this->isType('string')) + ->willReturn($request); + $request + ->expects($this->once()) + ->method('getParsedBody') ->willReturn([ 'test_name' => 'test_name', 'test_value' => $this->maskToken($mw, 'test_value123'), - ]) - ->shouldBeCalledOnce(); + ]); - $mw->process($requestProphecy->reveal(), $requestHandlerProphecy->reveal()); + $mw->process($request, $requestHandler); self::assertArrayNotHasKey('test_name', $storage); } @@ -383,57 +397,62 @@ public function testTokenIsRemovedFromStorageWhenPersistentModeIsOffOnFailure() 'test_name2' => 'test_value234', ]; - $streamProphecy = $this->prophesize(StreamInterface::class); - $streamProphecy - ->write('Failed CSRF check!') - ->shouldBeCalledOnce(); - - $responseProphecy = $this->prophesize(ResponseInterface::class); - - $responseProphecy - ->getBody() - ->willReturn($streamProphecy->reveal()) - ->shouldBeCalledOnce(); - - $responseProphecy - ->withStatus(400) - ->willReturn($responseProphecy->reveal()) - ->shouldBeCalledOnce(); - - $responseProphecy - ->withHeader('Content-Type', 'text/plain') - ->willReturn($responseProphecy->reveal()) - ->shouldBeCalledOnce(); - - $responseProphecy - ->withBody($streamProphecy->reveal()) - ->willReturn($responseProphecy->reveal()) - ->shouldBeCalledOnce(); - - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - $responseFactoryProphecy - ->createResponse() - ->willReturn($responseProphecy->reveal()); - - $requestHandlerProphecy = $this->prophesize(RequestHandlerInterface::class); - - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage, null, 1); + $stream = $this->createMock(StreamInterface::class); + $stream + ->expects($this->once()) + ->method('write') + ->with('Failed CSRF check!'); + + $response = $this->createMock(ResponseInterface::class); + + $response + ->expects($this->once()) + ->method('getBody') + ->willReturn($stream); + + $response + ->expects($this->once()) + ->method('withStatus') + ->with(400) + ->willReturn($response); + + $response + ->expects($this->once()) + ->method('withHeader') + ->with('Content-Type', 'text/plain') + ->willReturn($response); + + $response + ->expects($this->once()) + ->method('withBody') + ->with($stream) + ->willReturn($response); + + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + $responseFactory + ->expects($this->once()) + ->method('createResponse') + ->willReturn($response); + + $requestHandler = $this->createMock(RequestHandlerInterface::class); + + $mw = new Guard($responseFactory, 'test', $storage, null, 1); $mw->setStorage($storage); // pass $storage in by reference so we can inspect it later - $requestProphecy = $this->prophesize(ServerRequestInterface::class); - $requestProphecy - ->getMethod() - ->willReturn('GET') - ->shouldBeCalledOnce(); + $request = $this->createMock(ServerRequestInterface::class); + $request + ->expects($this->once()) + ->method('getMethod') + ->willReturn('GET'); - $requestProphecy - ->getParsedBody() + $request + ->expects($this->once()) + ->method('getParsedBody') ->willReturn([ 'test_name' => 'test_value123', - ]) - ->shouldBeCalledOnce(); + ]); - $mw->process($requestProphecy->reveal(), $requestHandlerProphecy->reveal()); + $mw->process($request, $requestHandler); $this->assertArrayNotHasKey('test_name', $storage); } @@ -445,66 +464,66 @@ public function testTokenInBodyOfGetIsInvalid() ]; // we set up a failure handler that we expect to be called because a GET cannot have a token - $self = $this; $failureHandlerCalled = 0; - $failureHandler = function () use ($self, &$failureHandlerCalled) { + $failureHandler = function () use (&$failureHandlerCalled) { $failureHandlerCalled++; - $responseProphecy = $self->prophesize(ResponseInterface::class); - return $responseProphecy->reveal(); + return $this->createMock(ResponseInterface::class); }; - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage, $failureHandler); + $mw = new Guard($responseFactory, 'test', $storage, $failureHandler); - $requestHandlerProphecy = $this->prophesize(RequestHandlerInterface::class); + $requestHandler = $this->createMock(RequestHandlerInterface::class); - $requestProphecy = $this->prophesize(ServerRequestInterface::class); - $requestProphecy - ->getMethod() - ->willReturn('GET') - ->shouldBeCalledOnce(); - $requestProphecy - ->getParsedBody() + $request = $this->createMock(ServerRequestInterface::class); + $request + ->expects($this->once()) + ->method('getMethod') + ->willReturn('GET'); + $request + ->expects($this->once()) + ->method('getParsedBody') ->willReturn([ 'test_name' => 'test_name', 'test_value' => 'test_value123', - ]) - ->shouldBeCalledOnce(); + ]); - $mw->process($requestProphecy->reveal(), $requestHandlerProphecy->reveal()); + $mw->process($request, $requestHandler); self::assertSame(1, $failureHandlerCalled); } public function testProcessAppendsNewTokensWhenPersistentTokenModeIsOff() { $storage = []; - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage); - - $responseProphecy = $this->prophesize(ResponseInterface::class); - - $requestProphecy = $this->prophesize(ServerRequestInterface::class); - $requestProphecy->getParsedBody()->willReturn(null)->shouldBeCalledOnce(); - $requestProphecy->getHeader(Argument::type('string'))->willReturn([])->shouldBeCalledTimes(2); - $requestProphecy - ->getMethod() - ->willReturn('GET') - ->shouldBeCalledOnce(); - - $requestProphecy - ->withAttribute(Argument::type('string'), Argument::type('string')) - ->willReturn($requestProphecy->reveal()) - ->shouldBeCalledTimes(2); - - $requestHandlerProphecy = $this->prophesize(RequestHandlerInterface::class); - - $requestHandlerProphecy - ->handle($requestProphecy) - ->willReturn($responseProphecy->reveal()) - ->shouldBeCalledOnce(); - - $mw->process($requestProphecy->reveal(), $requestHandlerProphecy->reveal()); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + $mw = new Guard($responseFactory, 'test', $storage); + + $response = $this->createMock(ResponseInterface::class); + + $request = $this->createMock(ServerRequestInterface::class); + $request->expects($this->once())->method('getParsedBody')->willReturn(null); + $request->expects($this->exactly(2))->method('getHeader')->with($this->isType('string'))->willReturn([]); + $request + ->expects($this->once()) + ->method('getMethod') + ->willReturn('GET'); + + $request + ->expects($this->exactly(2)) + ->method('withAttribute') + ->with($this->isType('string'), $this->isType('string')) + ->willReturn($request); + + $requestHandler = $this->createMock(RequestHandlerInterface::class); + + $requestHandler + ->expects($this->once()) + ->method('handle') + ->with($request) + ->willReturn($response); + + $mw->process($request, $requestHandler); } public function testProcessAppendsNewTokensWhenPersistentTokenModeIsOn() @@ -512,37 +531,37 @@ public function testProcessAppendsNewTokensWhenPersistentTokenModeIsOn() $storage = [ 'test_name123' => 'test_value123', ]; - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage, null, 200, 16, true); - - $responseProphecy = $this->prophesize(ResponseInterface::class); - - $requestProphecy = $this->prophesize(ServerRequestInterface::class); - $requestProphecy->getParsedBody()->willReturn(null)->shouldBeCalledOnce(); - $requestProphecy->getHeader(Argument::type('string'))->willReturn([])->shouldBeCalledTimes(2); - $requestProphecy - ->getMethod() - ->willReturn('GET') - ->shouldBeCalledOnce(); - - $requestProphecy - ->withAttribute('test_name', 'test_name123') - ->willReturn($requestProphecy->reveal()) - ->shouldBeCalledOnce(); - - $requestProphecy - ->withAttribute('test_value', Argument::type('string')) - ->willReturn($requestProphecy->reveal()) - ->shouldBeCalledOnce(); - - $requestHandlerProphecy = $this->prophesize(RequestHandlerInterface::class); - - $requestHandlerProphecy - ->handle($requestProphecy) - ->willReturn($responseProphecy->reveal()) - ->shouldBeCalledOnce(); - - $mw->process($requestProphecy->reveal(), $requestHandlerProphecy->reveal()); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + $mw = new Guard($responseFactory, 'test', $storage, null, 200, 16, true); + + $response = $this->createMock(ResponseInterface::class); + + $request = $this->createMock(ServerRequestInterface::class); + $request->expects($this->once())->method('getParsedBody')->willReturn(null); + $request->expects($this->exactly(2))->method('getHeader')->with($this->isType('string'))->willReturn([]); + $request + ->expects($this->once()) + ->method('getMethod') + ->willReturn('GET'); + + $request + ->expects($this->exactly(2)) + ->method('withAttribute') + ->withConsecutive( + ['test_name', 'test_name123'], + ['test_value', $this->isType('string')] + ) + ->willReturn($request); + + $requestHandler = $this->createMock(RequestHandlerInterface::class); + + $requestHandler + ->expects($this->once()) + ->method('handle') + ->with($request) + ->willReturn($response); + + $mw->process($request, $requestHandler); } public function testCanGetLastKeyPairFromIterator() @@ -551,11 +570,11 @@ public function testCanGetLastKeyPairFromIterator() 'test_key1' => 'value1', 'test_key2' => 'value2', ]); - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage, null, 1); + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + $mw = new Guard($responseFactory, 'test', $storage, null, 1); $enforceStorageLimitMethod = new ReflectionMethod($mw, 'getLastKeyPair'); - $enforceStorageLimitMethod->setAccessible(true); + $this->setAccessible($enforceStorageLimitMethod); $keyPair = $enforceStorageLimitMethod->invoke($mw); $this->assertIsArray($keyPair); @@ -564,7 +583,7 @@ public function testCanGetLastKeyPairFromIterator() $this->assertEquals('test_key2', $keyPair['test_name']); $unmaskTokenMethod = new ReflectionMethod($mw, 'unmaskToken'); - $unmaskTokenMethod->setAccessible(true); + $this->setAccessible($unmaskTokenMethod); $unmaskedToken = $unmaskTokenMethod->invoke($mw, $keyPair['test_value']); $this->assertEquals('value2', $unmaskedToken); } @@ -575,41 +594,39 @@ public function testTokenFromHeaderOnDelete() 'test_name' => 'test_value123', ]; - $responseProphecy = $this->prophesize(ResponseInterface::class) - ->willImplement(ResponseInterface::class); - - $requestHandlerProphecy = $this->prophesize(RequestHandlerInterface::class); - $requestHandlerProphecy - ->handle(Argument::type(ServerRequestInterface::class)) - ->willReturn($responseProphecy->reveal()) - ->shouldBeCalledOnce(); - - $responseFactoryProphecy = $this->prophesize(ResponseFactoryInterface::class); - - $mw = new Guard($responseFactoryProphecy->reveal(), 'test', $storage); - - $requestProphecy = $this->prophesize(ServerRequestInterface::class); - $requestProphecy - ->getMethod() - ->willReturn('DELETE') - ->shouldBeCalledOnce(); - $requestProphecy - ->withAttribute(Argument::type('string'), Argument::type('string')) - ->willReturn($requestProphecy->reveal()) - ->shouldBeCalledTimes(2); - $requestProphecy - ->getParsedBody() - ->willReturn([]) - ->shouldBeCalledOnce(); - $requestProphecy - ->getHeader('test_name') - ->willReturn(['test_name']) - ->shouldBeCalledOnce(); - $requestProphecy - ->getHeader('test_value') - ->willReturn([$this->maskToken($mw, 'test_value123')]) - ->shouldBeCalledOnce(); - - $mw->process($requestProphecy->reveal(), $requestHandlerProphecy->reveal()); + $response = $this->createMock(ResponseInterface::class); + + $requestHandler = $this->createMock(RequestHandlerInterface::class); + $requestHandler + ->expects($this->once()) + ->method('handle') + ->with($this->isInstanceOf(ServerRequestInterface::class)) + ->willReturn($response); + + $responseFactory = $this->createMock(ResponseFactoryInterface::class); + + $mw = new Guard($responseFactory, 'test', $storage); + + $request = $this->createMock(ServerRequestInterface::class); + $request + ->expects($this->once()) + ->method('getMethod') + ->willReturn('DELETE'); + $request + ->expects($this->exactly(2)) + ->method('withAttribute') + ->with($this->isType('string'), $this->isType('string')) + ->willReturn($request); + $request + ->expects($this->once()) + ->method('getParsedBody') + ->willReturn([]); + $request + ->expects($this->exactly(2)) + ->method('getHeader') + ->withConsecutive(['test_name'], ['test_value']) + ->willReturnOnConsecutiveCalls(['test_name'], [$this->maskToken($mw, 'test_value123')]); + + $mw->process($request, $requestHandler); } }