Skip to content

[client] Allow send objects that implements \JsonSerializable interface. #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
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
12 changes: 8 additions & 4 deletions pkg/enqueue/Client/MessageProducer.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ private function prepareBody(Message $message)
$contentType = $contentType ?: 'text/plain';
$body = (string) $body;
} elseif (is_array($body)) {
$body = $message->getBody();
$contentType = $message->getContentType();

if ($contentType && $contentType !== 'application/json') {
throw new \LogicException(sprintf('Content type "application/json" only allowed when body is array'));
}
Expand All @@ -79,11 +76,18 @@ private function prepareBody(Message $message)
}
});

$contentType = 'application/json';
$body = JSON::encode($body);
} elseif ($body instanceof \JsonSerializable) {
if ($contentType && $contentType !== 'application/json') {
throw new \LogicException(sprintf('Content type "application/json" only allowed when body is array'));
}

$contentType = 'application/json';
$body = JSON::encode($body);
} else {
throw new \InvalidArgumentException(sprintf(
'The message\'s body must be either null, scalar or array. Got: %s',
'The message\'s body must be either null, scalar, array or object (implements \JsonSerializable). Got: %s',
is_object($body) ? get_class($body) : gettype($body)
));
}
Expand Down
70 changes: 69 additions & 1 deletion pkg/enqueue/Tests/Client/MessageProducerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ public function testShouldThrowExceptionIfBodyIsObjectOnSend()
$producer = new MessageProducer($driver);

$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('The message\'s body must be either null, scalar or array. Got: stdClass');
$this->expectExceptionMessage('The message\'s body must be either null, scalar, array or object (implements \JsonSerializable). Got: stdClass');

$producer->send('topic', new \stdClass());
}
Expand Down Expand Up @@ -339,6 +339,66 @@ public function testShouldThrowExceptionIfBodyIsArrayWithObjectsInSubArraysInsid
$producer->send($queue, ['foo' => ['bar' => new \stdClass()]]);
}

public function testShouldSendJsonSerializableObjectAsJsonString()
{
$object = new JsonSerializableObject();

$driver = $this->createDriverStub();
$driver
->expects($this->once())
->method('sendToRouter')
->willReturnCallback(function (Message $message) {
self::assertSame('{"foo":"fooVal"}', $message->getBody());
self::assertSame('application/json', $message->getContentType());
})
;

$producer = new MessageProducer($driver);
$producer->send('topic', $object);
}

public function testShouldSendMessageJsonSerializableBodyAsJsonString()
{
$object = new JsonSerializableObject();

$message = new Message();
$message->setBody($object);

$driver = $this->createDriverStub();
$driver
->expects($this->once())
->method('sendToRouter')
->willReturnCallback(function (Message $message) {
self::assertSame('{"foo":"fooVal"}', $message->getBody());
self::assertSame('application/json', $message->getContentType());
})
;

$producer = new MessageProducer($driver);
$producer->send('topic', $message);
}

public function testThrowIfNotApplicationJsonContentTypeSetWithJsonSerializableBody()
{
$object = new JsonSerializableObject();

$message = new Message();
$message->setBody($object);
$message->setContentType('foo/bar');

$driver = $this->createDriverStub();
$driver
->expects($this->never())
->method('sendToRouter')
;

$this->expectException(\LogicException::class);
$this->expectExceptionMessage('Content type "application/json" only allowed when body is array');

$producer = new MessageProducer($driver);
$producer->send('topic', $message);
}

/**
* @return \PHPUnit_Framework_MockObject_MockObject|DriverInterface
*/
Expand All @@ -347,3 +407,11 @@ protected function createDriverStub()
return $this->createMock(DriverInterface::class);
}
}

class JsonSerializableObject implements \JsonSerializable
{
public function jsonSerialize()
{
return ['foo' => 'fooVal'];
}
};