Skip to content

Commit

Permalink
Merge pull request #2 from geosocio/iterable-result
Browse files Browse the repository at this point in the history
Support Iterable Results
  • Loading branch information
davidbarratt authored Oct 1, 2017
2 parents 105a244 + ece4a18 commit eea874e
Show file tree
Hide file tree
Showing 2 changed files with 164 additions and 1 deletion.
40 changes: 39 additions & 1 deletion src/EventListener/KernelViewListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,39 @@ public function onKernelView(GetResponseForControllerResultEvent $event) :? Resp
return null;
}

if (is_iterable($result)) {
$data = $result;

// Convert objects to arrays.
if ($result instanceof \Traversable) {
$data = iterator_to_array($result);
}

// Determine if array is a collection or just a standard array.
$bad = array_filter($data, function ($item) use ($request) {
if (!is_object($item)) {
return true;
}

if (!$this->normalizer->supportsNormalization($item, $request->getRequestFormat())) {
return true;
}

return false;
});

// If array is a collection and everything can be normalized,
// normalize each item before serialization.
if (!count($bad)) {
$result = array_map(function ($item) use ($request) {
return $this->normalizer->normalize($item, $request->getRequestFormat(), [
'groups' => $this->groupResolver->resolve($request, $item),
'enable_max_depth' => true,
]);
}, $data);
}
}

// If the normalizer cannot normalize the result, then there is nothing
// more than can be done without the serializer throwing an exception.
if (is_object($result) && !$this->normalizer->supportsNormalization($result, $request->getRequestFormat())) {
Expand All @@ -103,11 +136,16 @@ public function onKernelView(GetResponseForControllerResultEvent $event) :? Resp
break;
}

$groups = null;
if (is_object($result)) {
$groups = $this->groupResolver->resolve($request, $result);
}

$serializeEvent = new SerializeEvent(
$result,
$request->getRequestFormat(),
[
'groups' => $this->groupResolver->resolve($request, $result),
'groups' => $groups,
'enable_max_depth' => true,
],
$request
Expand Down
125 changes: 125 additions & 0 deletions tests/EventListener/KernelViewListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,131 @@ public function testOnKernelView(string $method)
$this->assertInstanceOf(Response::class, $response);
}

/**
* Test Kernel View Iterable Listener
*
* @dataProvider views
*
* @param string $method
*/
public function testOnKernelViewIterable(string $method)
{
$serializer = $this->createMock(SerializerInterface::class);
$normalizer = $this->createMock(NormalizerInterface::class);
$normalizer->expects($this->once())
->method('supportsNormalization')
->willReturn(true);

$encoder = $this->createMock(EncoderInterface::class);
$encoder->expects($this->once())
->method('supportsEncoding')
->willReturn(true);

$eventDispatcher = $this->createMock(EventDispatcherInterface::class);

$groupResolver = $this->createMock(ResponseGroupResolverInterface::class);

$listener = new KernelViewListener(
$serializer,
$normalizer,
$encoder,
$eventDispatcher,
$groupResolver
);

$request = $this->getMockBuilder(Request::class)
->disableOriginalConstructor()
->getMock();
$request->expects($this->exactly(4))
->method('getRequestFormat')
->willReturn('test');
$request->expects($this->once())
->method('getMethod')
->willReturn($method);

$result = new \ArrayIterator([
new \stdClass(),
]);

$event = $this->createMock(GetResponseForControllerResultEvent::class);
$event->expects($this->once())
->method('hasResponse')
->willReturn(false);
$event->expects($this->once())
->method('getRequest')
->willReturn($request);
$event->expects($this->once())
->method('getControllerResult')
->willReturn($result);

$response = $listener->onKernelView($event);

$this->assertInstanceOf(Response::class, $response);
}

/**
* Test Kernel View Iterable Listener
*
* @dataProvider views
*
* @param string $method
*/
public function testOnKernelViewBadIterable(string $method)
{
$serializer = $this->createMock(SerializerInterface::class);
$normalizer = $this->createMock(NormalizerInterface::class);
$normalizer->expects($this->once())
->method('supportsNormalization')
->willReturn(false);

$encoder = $this->createMock(EncoderInterface::class);
$encoder->expects($this->once())
->method('supportsEncoding')
->willReturn(true);

$eventDispatcher = $this->createMock(EventDispatcherInterface::class);

$groupResolver = $this->createMock(ResponseGroupResolverInterface::class);

$listener = new KernelViewListener(
$serializer,
$normalizer,
$encoder,
$eventDispatcher,
$groupResolver
);

$request = $this->getMockBuilder(Request::class)
->disableOriginalConstructor()
->getMock();
$request->expects($this->exactly(3))
->method('getRequestFormat')
->willReturn('test');
$request->expects($this->once())
->method('getMethod')
->willReturn($method);

$result = [
'token' => '12345',
'object' => new \stdClass(),
];

$event = $this->createMock(GetResponseForControllerResultEvent::class);
$event->expects($this->once())
->method('hasResponse')
->willReturn(false);
$event->expects($this->once())
->method('getRequest')
->willReturn($request);
$event->expects($this->once())
->method('getControllerResult')
->willReturn($result);

$response = $listener->onKernelView($event);

$this->assertInstanceOf(Response::class, $response);
}

/**
* Test Kernel View Listener
*/
Expand Down

0 comments on commit eea874e

Please sign in to comment.