From 12991dfe8d2dffca3388f5172b095eb5dc35e446 Mon Sep 17 00:00:00 2001 From: Jason McCreary Date: Fri, 7 Feb 2020 22:20:06 -0500 Subject: [PATCH] Add callback to stub responses --- src/Zttp.php | 36 +++++++++++++++++++- tests/ZttpTest.php | 85 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 117 insertions(+), 4 deletions(-) diff --git a/src/Zttp.php b/src/Zttp.php index e1630b4..eb1833c 100755 --- a/src/Zttp.php +++ b/src/Zttp.php @@ -4,10 +4,35 @@ class Zttp { + static $expectations; + static function __callStatic($method, $args) { return PendingZttpRequest::new()->{$method}(...$args); } + + static function stub($callback) + { + self::$expectations = collect($callback); + } + + static function clearStubs() + { + self::$expectations = null; + } + + static function stubHandler() + { + return function ($handler) { + return function ($request, $options) use ($handler) { + return (self::$expectations ?? collect()) + ->map + ->__invoke(new ZttpRequest($request), $options) + ->filter() + ->first(null, $handler($request, $options)); + }; + }; + } } class PendingZttpRequest @@ -114,7 +139,7 @@ function withDigestAuth($username, $password) function withCookies($cookies) { - return tap($this, function($request) use ($cookies) { + return tap($this, function ($request) use ($cookies) { return $this->options = array_merge_recursive($this->options, [ 'cookies' => $cookies, ]); @@ -199,6 +224,7 @@ function buildHandlerStack() { return tap(\GuzzleHttp\HandlerStack::create(), function ($stack) { $stack->push($this->buildBeforeSendingHandler()); + $stack->push(Zttp::stubHandler()); }); } @@ -349,6 +375,14 @@ function __call($method, $args) } } +class ZttpResponseStub extends ZttpResponse +{ + static function create($body = null, $status = 200, $headers = []) + { + return \GuzzleHttp\Promise\promise_for(new \GuzzleHttp\Psr7\Response($status, $headers, $body)); + } +} + class ConnectionException extends \Exception {} function tap($value, $callback) { diff --git a/tests/ZttpTest.php b/tests/ZttpTest.php index e5a3189..7a20679 100644 --- a/tests/ZttpTest.php +++ b/tests/ZttpTest.php @@ -1,8 +1,8 @@ get($this->url('/basic-auth')); + $response = Zttp::withBasicAuth('zttp', 'secret')->get($this->url('/basic-auth')); - $this->assertTrue($response->isOk()); + $this->assertTrue($response->isOk()); } /** @test */ @@ -518,6 +524,79 @@ function cookies_can_be_shared_between_requests() $response = Zttp::get($this->url('/get')); $this->assertEquals([], $response->json()['cookies']); } + + /** @test */ + function responses_can_be_stubbed() + { + Zttp::stub(function ($request, $options) { + return \Zttp\ZttpResponseStub::create('stubbed ' . $request->method() . ' response'); + }); + + $this->assertEquals('stubbed GET response', Zttp::get('/foo')->body()); + $this->assertEquals('stubbed POST response', Zttp::post('/bar')->body()); + $this->assertEquals('stubbed PUT response', Zttp::put('/baz')->body()); + } + + /** @test */ + function responses_can_be_stubbed_and_unstubbed() + { + Zttp::stub(function ($request, $options) { + return \Zttp\ZttpResponseStub::create('stubbed response'); + }); + + $stubbedResponse = Zttp::get($this->url('/get')); + $this->assertEquals($stubbedResponse, $stubbedResponse->body()); + + Zttp::clearStubs(); + + $response = Zttp::get($this->url('/get')); + $this->assertNotEquals('stubbed response', $response->body()); + } + + /** @test */ + function responses_which_are_not_stubbed_are_sent() + { + Zttp::stub(function ($request, $options) { + if ($request->method() === 'POST') { + return \Zttp\ZttpResponseStub::create('stubbed response'); + } + }); + + $stubbedResponse = Zttp::post('/stubbed'); + $this->assertEquals('stubbed response', $stubbedResponse->body()); + + $this->assertNotEquals('stubbed response', Zttp::get($this->url('/get'))->body()); + } + + /** @test */ + function stub_callback_is_fired_after_other_callbacks() + { + $fired = false; + Zttp::stub(function ($request, $options) use (&$fired) { + if ($fired) { + return \Zttp\ZttpResponseStub::create('stubbed response'); + } + }); + + $response = Zttp::beforeSending(function ($request, $options) use (&$fired) { + $fired = true; + })->get('/get'); + + $this->assertEquals('stubbed response', $response->body()); + } + + /** + * @test + * @expectedException \Zttp\ConnectionException + */ + function stub_callback_can_throw_an_exception() + { + Zttp::stub(function ($request, $options) { + throw new \Zttp\ConnectionException(); + }); + + Zttp::get('/oops'); + } } class ZttpServer