request = new ServerRequest(); $this->response = new Response(); $this->next = new NextMock(); $this->middleware = new MiddlewareMock(); $this->dispatcher = new Dispatcher(); } private function getMethodMap() { return new MethodMap($this->dispatcher); } // ------------------------------------------------------------------------- public function testDispatchesMiddlewareWithMatchingMethod() { $this->request = $this->request->withMethod('GET'); $map = $this->getMethodMap(); $map->register('GET', $this->middleware); $map($this->request, $this->response, $this->next); $this->assertTrue($this->middleware->called); } public function testTreatsMethodNamesCaseSensitively() { $this->request = $this->request->withMethod('get'); $middlewareUpper = new MiddlewareMock(); $middlewareLower = new MiddlewareMock(); $map = $this->getMethodMap(); $map->register('GET', $middlewareUpper); $map->register('get', $middlewareLower); $map($this->request, $this->response, $this->next); $this->assertTrue($middlewareLower->called); } public function testDispatchesWildcardMiddlewareWithNonMatchingMethod() { $this->request = $this->request->withMethod('GET'); $map = $this->getMethodMap(); $map->register('*', $this->middleware); $map($this->request, $this->response, $this->next); $this->assertTrue($this->middleware->called); } public function testDispatchesGetMiddlewareForHeadByDefault() { $this->request = $this->request->withMethod('HEAD'); $map = $this->getMethodMap(); $map->register('GET', $this->middleware); $map($this->request, $this->response, $this->next); $this->assertTrue($this->middleware->called); } public function testRegistersMiddlewareForMultipleMethods() { $map = $this->getMethodMap(); $map->register('GET,POST', $this->middleware); $this->request = $this->request->withMethod('GET'); $map($this->request, $this->response, $this->next); $this->request = $this->request->withMethod('POST'); $map($this->request, $this->response, $this->next); $this->assertEquals(2, $this->middleware->callCount); } public function testSettingNullDeregistersMiddleware() { $this->request = $this->request->withMethod('POST'); $map = $this->getMethodMap(); $map->register('POST', $this->middleware); $map->register('POST', null); $response = $map($this->request, $this->response, $this->next); $this->assertEquals(405, $response->getStatusCode()); } public function testSetsStatusTo200ForOptions() { $this->request = $this->request->withMethod('OPTIONS'); $map = $this->getMethodMap(); $map->register('GET', $this->middleware); $response = $map($this->request, $this->response, $this->next); $this->assertEquals(200, $response->getStatusCode()); } public function testStopsPropagatingAfterOptions() { $this->request = $this->request->withMethod('OPTIONS'); $map = $this->getMethodMap(); $map->register('GET', $this->middleware); $map($this->request, $this->response, $this->next); $this->assertFalse($this->next->called); } /** @dataProvider allowedMethodProvider */ public function testSetsAllowHeaderForOptions($methodsDeclared, $methodsAllowed) { $this->request = $this->request->withMethod('OPTIONS'); $map = $this->getMethodMap(); foreach ($methodsDeclared as $method) { $map->register($method, $this->middleware); } $response = $map($this->request, $this->response, $this->next); $this->assertContainsEach($methodsAllowed, $response->getHeaderLine('Allow')); } /** @dataProvider allowedMethodProvider */ public function testSetsStatusTo405ForBadMethod() { $this->request = $this->request->withMethod('POST'); $map = $this->getMethodMap(); $map->register('GET', $this->middleware); $response = $map($this->request, $this->response, $this->next); $this->assertEquals(405, $response->getStatusCode()); } /** * @coversNothing * @dataProvider allowedMethodProvider */ public function testStopsPropagatingAfterBadMethod() { $this->request = $this->request->withMethod('POST'); $map = $this->getMethodMap(); $map->register('GET', $this->middleware); $map($this->request, $this->response, $this->next); $this->assertFalse($this->next->called); } /** @dataProvider allowedMethodProvider */ public function testSetsAllowHeaderForBadMethod($methodsDeclared, $methodsAllowed) { $this->request = $this->request->withMethod('BAD'); $map = $this->getMethodMap(); foreach ($methodsDeclared as $method) { $map->register($method, $this->middleware); } $response = $map($this->request, $this->response, $this->next); $this->assertContainsEach($methodsAllowed, $response->getHeaderLine('Allow')); } public function allowedMethodProvider() { return [ [['GET'], ['GET', 'HEAD', 'OPTIONS']], [['GET', 'POST'], ['GET', 'POST', 'HEAD', 'OPTIONS']], [['POST'], ['POST', 'OPTIONS']], [['POST'], ['POST', 'OPTIONS']], [['GET', 'PUT,DELETE'], ['GET', 'PUT', 'DELETE', 'HEAD', 'OPTIONS']], ]; } private function assertContainsEach($expectedList, $actual) { foreach ($expectedList as $expected) { if (strpos($actual, $expected) === false) { $this->assertTrue(false, "'$actual' does not contain expected '$expected'"); } } $this->assertTrue(true); } }