1<?php
2
3declare(strict_types=1);
4
5namespace JMS\Serializer\Tests\Serializer\EventDispatcher\Subscriber;
6
7use JMS\Serializer\DeserializationContext;
8use JMS\Serializer\EventDispatcher\EventDispatcher;
9use JMS\Serializer\EventDispatcher\ObjectEvent;
10use JMS\Serializer\EventDispatcher\Subscriber\SymfonyValidatorSubscriber;
11use JMS\Serializer\EventDispatcher\Subscriber\SymfonyValidatorValidatorSubscriber;
12use JMS\Serializer\SerializerBuilder;
13use PHPUnit\Framework\TestCase;
14use Symfony\Component\Validator\ConstraintViolation;
15use Symfony\Component\Validator\ConstraintViolationList;
16
17class SymfonyValidatorValidatorSubscriberTest extends TestCase
18{
19    private $validator;
20
21    /** @var SymfonyValidatorSubscriber */
22    private $subscriber;
23
24    public function testValidate()
25    {
26        $obj = new \stdClass();
27
28        $this->validator->expects($this->once())
29            ->method('validate')
30            ->with($obj, null, ['foo'])
31            ->will($this->returnValue(new ConstraintViolationList()));
32
33        $context = DeserializationContext::create()->setAttribute('validation_groups', ['foo']);
34
35        $this->subscriber->onPostDeserialize(new ObjectEvent($context, $obj, []));
36    }
37
38    /**
39     * @expectedException \JMS\Serializer\Exception\ValidationFailedException
40     * @expectedExceptionMessage Validation failed with 1 error(s).
41     */
42    public function testValidateThrowsExceptionWhenListIsNotEmpty()
43    {
44        $obj = new \stdClass();
45
46        $this->validator->expects($this->once())
47            ->method('validate')
48            ->with($obj, null, ['foo'])
49            ->will($this->returnValue(new ConstraintViolationList([new ConstraintViolation('foo', 'foo', [], 'a', 'b', 'c')])));
50
51        $context = DeserializationContext::create()->setAttribute('validation_groups', ['foo']);
52
53        $this->subscriber->onPostDeserialize(new ObjectEvent($context, $obj, []));
54    }
55
56    public function testValidatorIsNotCalledWhenNoGroupsAreSet()
57    {
58        $this->validator->expects($this->never())
59            ->method('validate');
60
61        $this->subscriber->onPostDeserialize(new ObjectEvent(DeserializationContext::create(), new \stdClass(), []));
62    }
63
64    public function testValidationIsOnlyPerformedOnRootObject()
65    {
66        $this->validator->expects($this->once())
67            ->method('validate')
68            ->with($this->isInstanceOf('JMS\Serializer\Tests\Fixtures\AuthorList'), null, ['Foo'])
69            ->will($this->returnValue(new ConstraintViolationList()));
70
71        $subscriber = $this->subscriber;
72        $list = SerializerBuilder::create()
73            ->configureListeners(static function (EventDispatcher $dispatcher) use ($subscriber) {
74                $dispatcher->addSubscriber($subscriber);
75            })
76            ->build()
77            ->deserialize(
78                '{"authors":[{"full_name":"foo"},{"full_name":"bar"}]}',
79                'JMS\Serializer\Tests\Fixtures\AuthorList',
80                'json',
81                DeserializationContext::create()->setAttribute('validation_groups', ['Foo'])
82            );
83
84        self::assertCount(2, $list);
85    }
86
87    protected function setUp()
88    {
89        $this->validator = $this->getMockBuilder('Symfony\Component\Validator\Validator\ValidatorInterface')->getMock();
90        $this->subscriber = new SymfonyValidatorValidatorSubscriber($this->validator);
91    }
92}
93