<?php
namespace GuzzleHttp\Test\Handler;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7\Stream;
use GuzzleHttp\TransferStats;
use PHPUnit\Framework\TestCase;
/**
* @covers \GuzzleHttp\Handler\MockHandler
*/
class MockHandlerTest extends TestCase
{
public function testReturnsMockResponse()
{
$res = new Response();
$mock = new MockHandler([$res]);
$request = new Request('GET', 'http://example.com');
$p = $mock($request, []);
self::assertSame($res, $p->wait());
}
public function testIsCountable()
{
$res = new Response();
$mock = new MockHandler([$res, $res]);
self::assertCount(2, $mock);
}
public function testEmptyHandlerIsCountable()
{
self::assertCount(0, new MockHandler());
}
public function testEnsuresEachAppendOnCreationIsValid()
{
$this->expectException(\TypeError::class);
new MockHandler(['a']);
}
public function testEnsuresEachAppendIsValid()
{
$mock = new MockHandler();
$this->expectException(\TypeError::class);
$mock->append(['a']);
}
public function testCanQueueExceptions()
{
$e = new \Exception('a');
$mock = new MockHandler([$e]);
$request = new Request('GET', 'http://example.com');
$p = $mock($request, []);
try {
$p->wait();
self::fail();
} catch (\Exception $e2) {
self::assertSame($e, $e2);
}
}
public function testCanGetLastRequestAndOptions()
{
$res = new Response();
$mock = new MockHandler([$res]);
$request = new Request('GET', 'http://example.com');
$mock($request, ['foo' => 'bar']);
self::assertSame($request, $mock->getLastRequest());
self::assertSame(['foo' => 'bar'], $mock->getLastOptions());
}
public function testSinkFilename()
{
$filename = \sys_get_temp_dir() . '/mock_test_' . \uniqid();
$res = new Response(200, [], 'TEST CONTENT');
$mock = new MockHandler([$res]);
$request = new Request('GET', '/');
$p = $mock($request, ['sink' => $filename]);
$p->wait();
self::assertFileExists($filename);
self::assertStringEqualsFile($filename, 'TEST CONTENT');
\unlink($filename);
}
public function testSinkResource()
{
$file = \tmpfile();
$meta = \stream_get_meta_data($file);
$res = new Response(200, [], 'TEST CONTENT');
$mock = new MockHandler([$res]);
$request = new Request('GET', '/');
$p = $mock($request, ['sink' => $file]);
$p->wait();
self::assertFileExists($meta['uri']);
self::assertStringEqualsFile($meta['uri'], 'TEST CONTENT');
}
public function testSinkStream()
{
$stream = new Stream(\tmpfile());
$res = new Response(200, [], 'TEST CONTENT');
$mock = new MockHandler([$res]);
$request = new Request('GET', '/');
$p = $mock($request, ['sink' => $stream]);
$p->wait();
self::assertFileExists($stream->getMetadata('uri'));
self::assertStringEqualsFile($stream->getMetadata('uri'), 'TEST CONTENT');
}
public function testCanEnqueueCallables()
{
$r = new Response();
$fn = static function ($req, $o) use ($r) {
return $r;
};
$mock = new MockHandler([$fn]);
$request = new Request('GET', 'http://example.com');
$p = $mock($request, ['foo' => 'bar']);
self::assertSame($r, $p->wait());
}
public function testEnsuresOnHeadersIsCallable()
{
$res = new Response();
$mock = new MockHandler([$res]);
$request = new Request('GET', 'http://example.com');
$this->expectException(\InvalidArgumentException::class);
$mock($request, ['on_headers' => 'error!']);
}
public function testRejectsPromiseWhenOnHeadersFails()
{
$res = new Response();
$mock = new MockHandler([$res]);
$request = new Request('GET', 'http://example.com');
$promise = $mock($request, [
'on_headers' => static function () {
throw new \Exception('test');
}
]);
$this->expectException(RequestException::class);
$this->expectExceptionMessage('An error was encountered during the on_headers event');
$promise->wait();
}
public function testInvokesOnFulfilled()
{
$res = new Response();
$mock = new MockHandler([$res], static function ($v) use (&$c) {
$c = $v;
});
$request = new Request('GET', 'http://example.com');
$mock($request, [])->wait();
self::assertSame($res, $c);
}
public function testInvokesOnRejected()
{
$e = new \Exception('a');
$c = null;
$mock = new MockHandler([$e], null, static function ($v) use (&$c) {
$c = $v;
});
$request = new Request('GET', 'http://example.com');
$mock($request, [])->wait(false);
self::assertSame($e, $c);
}
public function testThrowsWhenNoMoreResponses()
{
$mock = new MockHandler();
$request = new Request('GET', 'http://example.com');
$this->expectException(\OutOfBoundsException::class);
$mock($request, []);
}
public function testCanCreateWithDefaultMiddleware()
{
$r = new Response(500);
$mock = MockHandler::createWithMiddleware([$r]);
$request = new Request('GET', 'http://example.com');
$this->expectException(BadResponseException::class);
$mock($request, ['http_errors' => true])->wait();
}
public function testInvokesOnStatsFunctionForResponse()
{
$res = new Response();
$mock = new MockHandler([$res]);
$request = new Request('GET', 'http://example.com');
/** @var TransferStats|null $stats */
$stats = null;
$onStats = static function (TransferStats $s) use (&$stats) {
$stats = $s;
};
$p = $mock($request, ['on_stats' => $onStats]);
$p->wait();
self::assertSame($res, $stats->getResponse());
self::assertSame($request, $stats->getRequest());
}
public function testInvokesOnStatsFunctionForError()
{
$e = new \Exception('a');
$c = null;
$mock = new MockHandler([$e], null, static function ($v) use (&$c) {
$c = $v;
});
$request = new Request('GET', 'http://example.com');
/** @var TransferStats|null $stats */
$stats = null;
$onStats = static function (TransferStats $s) use (&$stats) {
$stats = $s;
};
$mock($request, ['on_stats' => $onStats])->wait(false);
self::assertSame($e, $stats->getHandlerErrorData());
self::assertNull($stats->getResponse());
self::assertSame($request, $stats->getRequest());
}
public function testTransferTime()
{
$e = new \Exception('a');
$c = null;
$mock = new MockHandler([$e], null, static function ($v) use (&$c) {
$c = $v;
});
$request = new Request('GET', 'http://example.com');
$stats = null;
$onStats = static function (TransferStats $s) use (&$stats) {
$stats = $s;
};
$mock($request, ['on_stats' => $onStats, 'transfer_time' => 0.4])->wait(false);
self::assertEquals(0.4, $stats->getTransferTime());
}
public function testResetQueue()
{
$mock = new MockHandler([new Response(200), new Response(204)]);
self::assertCount(2, $mock);
$mock->reset();
self::assertEmpty($mock);
$mock->append(new Response(500));
self::assertCount(1, $mock);
}
}