diff --git a/src/RequestFactory.php b/src/RequestFactory.php index c52f067..865154d 100644 --- a/src/RequestFactory.php +++ b/src/RequestFactory.php @@ -16,6 +16,20 @@ */ use Psr\Http\Message\RequestFactoryInterface; use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\UriInterface; +use InvalidArgumentException; + +/** + * Import functions + */ +use function json_encode; +use function json_last_error; +use function json_last_error_msg; + +/** + * Import constants + */ +use const JSON_ERROR_NONE; /** * HTTP Request Message Factory @@ -32,4 +46,40 @@ public function createRequest(string $method, $uri) : RequestInterface { return new Request($method, $uri); } + + /** + * Creates JSON request + * + * @param string $method + * @param string|UriInterface|null $uri + * @param mixed $data + * @param int $options + * @param int $depth + * + * @return RequestInterface + * + * @throws InvalidArgumentException + * If the data cannot be encoded. + */ + public function createJsonRequest( + string $method, + $uri, + $data, + int $options = 0, + int $depth = 512 + ) : RequestInterface { + json_encode(''); // reset previous error... + $content = json_encode($data, $options, $depth); + if (JSON_ERROR_NONE <> json_last_error()) { + throw new InvalidArgumentException(json_last_error_msg()); + } + + $request = new Request($method, $uri, [ + 'Content-Type' => 'application/json; charset=UTF-8', + ]); + + $request->getBody()->write($content); + + return $request; + } } diff --git a/tests/RequestFactoryTest.php b/tests/RequestFactoryTest.php index eca5de0..7e0b6a8 100644 --- a/tests/RequestFactoryTest.php +++ b/tests/RequestFactoryTest.php @@ -63,4 +63,32 @@ public function testCreateRequestWithUriAsString() : void $this->assertInstanceOf(UriInterface::class, $request->getUri()); $this->assertEquals($uri, (string) $request->getUri()); } + + /** + * @return void + */ + public function testCreateJsonRequest() : void + { + $payload = ['foo' => '']; + $options = \JSON_HEX_TAG; + + $request = (new RequestFactory)->createJsonRequest('GET', '/foo', $payload, $options); + + $this->assertInstanceOf(RequestInterface::class, $request); + $this->assertSame('GET', $request->getMethod()); + $this->assertSame('/foo', (string) $request->getUri()); + $this->assertSame('application/json; charset=UTF-8', $request->getHeaderLine('Content-Type')); + $this->assertSame(\json_encode($payload, $options), (string) $request->getBody()); + } + + /** + * @return void + */ + public function testCreateJsonRequestWithInvalidJson() : void + { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Maximum stack depth exceeded'); + + $request = (new RequestFactory)->createJsonRequest('GET', '/', [[]], 0, 1); + } }