request = $this->prophesize('Psr\Http\Message\ServerRequestInterface'); $this->response = $this->prophesize('Psr\Http\Message\ResponseInterface'); $this->next = function ($request, $response) { return $response; }; $this->dispatcher = $this->prophesize('WellRESTed\Dispatching\DispatcherInterface'); $this->dispatcher->dispatch(Argument::cetera())->will(function ($args) { list($middleware, $request, $response, $next) = $args; return $middleware($request, $response, $next); }); } /** * @covers ::__construct */ public function testCreatesInstance() { $stack = new DispatchStack($this->dispatcher->reveal()); $this->assertNotNull($stack); } /** * @covers ::add */ public function testAddIsFluid() { $stack = new DispatchStack($this->dispatcher->reveal()); $this->assertSame($stack, $stack->add("middleware1")); } /** * @covers ::__invoke */ public function testDispachesMiddlewareInOrderAdded() { // Each middelware will add its "name" to this array. $callOrder = []; $stack = new DispatchStack($this->dispatcher->reveal()); $stack->add(function ($request, $response, $next) use (&$callOrder) { $callOrder[] = "first"; return $next($request, $response); }); $stack->add(function ($request, $response, $next) use (&$callOrder) { $callOrder[] = "second"; return $next($request, $response); }); $stack->add(function ($request, $response, $next) use (&$callOrder) { $callOrder[] = "third"; return $next($request, $response); }); $stack($this->request->reveal(), $this->response->reveal(), $this->next); $this->assertEquals(["first", "second", "third"], $callOrder); } /** * @covers ::__invoke */ public function testCallsNextAfterDispatchingEmptyStack() { $nextCalled = false; $next = function ($request, $response) use (&$nextCalled) { $nextCalled = true; return $response; }; $stack = new DispatchStack($this->dispatcher->reveal()); $stack($this->request->reveal(), $this->response->reveal(), $next); $this->assertTrue($nextCalled); } /** * @covers ::__invoke */ public function testCallsNextAfterDispatchingStack() { $nextCalled = false; $next = function ($request, $response) use (&$nextCalled) { $nextCalled = true; return $response; }; $middleware = function ($request, $response, $next) use (&$callOrder) { return $next($request, $response); }; $stack = new DispatchStack($this->dispatcher->reveal()); $stack->add($middleware); $stack->add($middleware); $stack->add($middleware); $stack($this->request->reveal(), $this->response->reveal(), $next); $this->assertTrue($nextCalled); } /** * @covers ::__invoke */ public function testDoesNotCallNextWhenStackStopsEarly() { $nextCalled = false; $next = function ($request, $response) use (&$nextCalled) { $nextCalled = true; return $response; }; $middlewareGo = function ($request, $response, $next) use (&$callOrder) { return $next($request, $response); }; $middlewareStop = function ($request, $response, $next) use (&$callOrder) { return $response; }; $stack = new DispatchStack($this->dispatcher->reveal()); $stack->add($middlewareGo); $stack->add($middlewareStop); $stack->add($middlewareStop); $stack($this->request->reveal(), $this->response->reveal(), $next); $this->assertFalse($nextCalled); } }