Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion src/Zttp.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
]);
Expand Down Expand Up @@ -199,6 +224,7 @@ function buildHandlerStack()
{
return tap(\GuzzleHttp\HandlerStack::create(), function ($stack) {
$stack->push($this->buildBeforeSendingHandler());
$stack->push(Zttp::stubHandler());
});
}

Expand Down Expand Up @@ -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) {
Expand Down
85 changes: 82 additions & 3 deletions tests/ZttpTest.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php

use PHPUnit\Framework\TestCase;
use Zttp\Zttp;
use Zttp\ZttpResponse;
use PHPUnit\Framework\TestCase;

class ZttpTest extends TestCase
{
Expand All @@ -11,6 +11,12 @@ public static function setUpBeforeClass()
ZttpServer::start();
}

protected function tearDown()
{
Zttp::clearStubs();
parent::tearDown();
}

function url($url)
{
return vsprintf('%s/%s', [
Expand Down Expand Up @@ -474,9 +480,9 @@ function response_can_use_macros()
/** @test */
function can_use_basic_auth()
{
$response = Zttp::withBasicAuth('zttp', 'secret')->get($this->url('/basic-auth'));
$response = Zttp::withBasicAuth('zttp', 'secret')->get($this->url('/basic-auth'));

$this->assertTrue($response->isOk());
$this->assertTrue($response->isOk());
}

/** @test */
Expand Down Expand Up @@ -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
Expand Down