Completed
Pull Request — 3.x (#768)
by
unknown
05:56 queued 04:20
created

ProxyQueryTest::testAddOrderedColumnsCompositeId()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 19
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the Sonata Project package.
5
 *
6
 * (c) Thomas Rabaix <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sonata\DoctrineORMAdminBundle\Tests\Datagrid;
13
14
use Doctrine\DBAL\Types\Type;
15
use Doctrine\ORM\EntityManager;
16
use Doctrine\ORM\Query\Expr\From;
17
use Doctrine\ORM\Query\Expr\OrderBy;
18
use Doctrine\ORM\Query\Expr\Select;
19
use Doctrine\ORM\Tools\SchemaTool;
20
use PHPUnit\Framework\TestCase;
21
use Sonata\DoctrineORMAdminBundle\Datagrid\ProxyQuery;
22
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\DoctrineType\UuidType;
23
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Util\NonIntegerIdentifierTestClass;
24
use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper;
25
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity;
26
27
class ProxyQueryTest extends TestCase
28
{
29
    const DOUBLE_NAME_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity';
30
    const COMPOSITE_ID_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity';
31
32
    /**
33
     * @var EntityManager
34
     */
35
    private $em;
36
37
    public static function setUpBeforeClass()
38
    {
39
        if (!Type::hasType('uuid')) {
40
            Type::addType('uuid', 'Sonata\DoctrineORMAdminBundle\Tests\Fixtures\DoctrineType\UuidType');
41
        }
42
    }
43
44
    protected function setUp()
45
    {
46
        $this->em = DoctrineTestHelper::createTestEntityManager();
47
48
        $schemaTool = new SchemaTool($this->em);
49
        $classes = [
50
            $this->em->getClassMetadata(self::DOUBLE_NAME_CLASS),
51
        ];
52
53
        try {
54
            $schemaTool->dropSchema($classes);
55
        } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
56
        }
57
58
        try {
59
            $schemaTool->createSchema($classes);
60
        } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
61
        }
62
    }
63
64
    protected function tearDown()
65
    {
66
        $this->em = null;
67
    }
68
69
    public function dataGetFixedQueryBuilder()
70
    {
71
        return [
72
            ['aaa', 'bbb', 'id', 'id_idx', 33, Type::INTEGER],
73
            ['aaa', 'bbb', 'associatedId', 'associatedId_idx', 33, null],
74
            ['aaa', 'bbb', 'id.value', 'id_value_idx', 33, Type::INTEGER],
75
            ['aaa', 'bbb', 'id.uuid', 'id_uuid_idx', new NonIntegerIdentifierTestClass('80fb6f91-bba1-4d35-b3d4-e06b24494e85'), UuidType::NAME],
76
        ];
77
    }
78
79
    /**
80
     * @dataProvider dataGetFixedQueryBuilder
81
     *
82
     * @param $class
83
     * @param $alias
84
     * @param $id
85
     */
86
    public function testGetFixedQueryBuilder($class, $alias, $id, $expectedId, $value, $identifierType)
87
    {
88
        $meta = $this->createMock('Doctrine\ORM\Mapping\ClassMetadataInfo');
89
        $meta->expects($this->any())
90
            ->method('getIdentifierFieldNames')
91
            ->willReturn([$id]);
92
        $meta->expects($this->any())
93
            ->method('getTypeOfField')
94
            ->willReturn($identifierType);
95
96
        $mf = $this->createMock('Doctrine\ORM\Mapping\ClassMetadataFactory');
97
        $mf->expects($this->any())
98
            ->method('getMetadataFor')
99
            ->with($this->equalTo($class))
100
            ->willReturn($meta);
101
102
        $platform = $this->createMock('Doctrine\DBAL\Platforms\PostgreSqlPlatform');
103
104
        $conn = $this->createMock('Doctrine\DBAL\Connection');
105
        $conn->expects($this->any())
106
            ->method('getDatabasePlatform')
107
            ->willReturn($platform);
108
109
        $em = $this->createMock('Doctrine\ORM\EntityManager');
110
        $em->expects($this->any())
111
            ->method('getMetadataFactory')
112
            ->willReturn($mf);
113
        $em->expects($this->any())
114
            ->method('getConnection')
115
            ->willReturn($conn);
116
117
        // NEXT MAJOR: Replace this when dropping PHP < 5.6
118
        // $q = $this->createMock('PDOStatement');
119
        $q = $this->getMockBuilder('stdClass')
120
            ->setMethods(['execute'])
121
            ->getMock();
122
        $q->expects($this->any())
123
            ->method('execute')
124
            ->willReturn([[$id => $value]]);
125
126
        $qb = $this->getMockBuilder('Doctrine\ORM\QueryBuilder')
127
            ->setConstructorArgs([$em])
128
            ->getMock();
129
        $qb->expects($this->any())
130
            ->method('getEntityManager')
131
            ->willReturn($em);
132
        $qb->expects($this->any())
133
            ->method('getQuery')
134
            ->willReturn($q);
135
        $qb->expects($this->once())
136
            ->method('setParameter')
137
            ->with($this->equalTo($expectedId), $this->equalTo([$value]));
138
        $qb->expects($this->any())
139
            ->method('getDQLPart')
140
            ->will($this->returnCallBack(function ($part) use ($class, $alias) {
141
                $parts = [
142
                    'from' => [new From($class, $alias)],
143
                    'orderBy' => [new OrderBy('whatever', 'DESC')],
144
                ];
145
146
                return $parts[$part];
147
            }));
148
        $qb->expects($this->once())
149
            ->method('addOrderBy')
150
            ->with("$alias.$id", null);
151
        $qb->expects($this->once())
152
            ->method('getRootEntities')
153
            ->willReturn([$class]);
154
        $qb->expects($this->exactly(2))
155
            ->method('getRootAliases')
156
            ->willReturn([$alias]);
157
158
        $pq = $this->getMockBuilder('Sonata\DoctrineORMAdminBundle\Datagrid\ProxyQuery')
159
            ->setConstructorArgs([$qb])
160
            ->setMethods(['a'])
161
            ->getMock();
162
163
        /* Work */
164
165
        $pq->execute();
166
    }
167
168
    public function testAddOrderedColumns()
169
    {
170
        $qb = $this->em->createQueryBuilder()
171
                       ->select('o.id')
172
                       ->distinct()
173
                       ->from(self::DOUBLE_NAME_CLASS, 'o')
174
                       ->orderBy('o.name', 'ASC')
175
                       ->addOrderBy('o.name2', 'DESC');
176
177
        $pq = $this->getMockBuilder('Sonata\DoctrineORMAdminBundle\Datagrid\ProxyQuery')
178
                   ->disableOriginalConstructor()
179
                   ->getMock();
180
181
        $reflection = new \ReflectionClass(get_class($pq));
182
        $method = $reflection->getMethod('addOrderedColumns');
183
        $method->setAccessible(true);
184
        $method->invoke($pq, $qb, []);
185
186
        $dqlPart = $qb->getDqlPart('select');
187
        $this->assertCount(3, $dqlPart);
188
        $this->assertEquals('o.id', $dqlPart[0]);
189
        $this->assertEquals('o.name', $dqlPart[1]);
190
        $this->assertEquals('o.name2', $dqlPart[2]);
191
    }
192
193
    public function testSetHint()
194
    {
195
        $entity1 = new DoubleNameEntity(1, 'Foo', null);
196
        $entity2 = new DoubleNameEntity(2, 'Bar', null);
197
198
        $this->em->persist($entity1);
199
        $this->em->persist($entity2);
200
        $this->em->flush();
201
202
        $qb = $this->em->createQueryBuilder()
203
                       ->select('o.id')
204
                       ->from(self::DOUBLE_NAME_CLASS, 'o');
205
206
        $pq = new ProxyQuery($qb);
207
        $pq->setHint(
208
            \Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER,
209
            'Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Query\FooWalker'
210
        );
211
        $pq->setHint('hint', 'value');
212
213
        $result = $pq->execute();
214
215
        $this->assertEquals(2, $result[0]['id']);
216
    }
217
218
    public function testAddOrderedColumnsCompositeId()
219
    {
220
        $qb = $this->em->createQueryBuilder()
221
                       ->select('IDENTITY(o.id1) as id1, IDENTITY(o.id2) as id2')
222
                       ->distinct()
223
                       ->from(self::COMPOSITE_ID_CLASS, 'o')
224
                       ->orderBy('o.id1', 'ASC')
225
                       ->addOrderBy('o.id2', 'ASC');
226
227
        $pq = $this->getMockBuilder('Sonata\DoctrineORMAdminBundle\Datagrid\ProxyQuery')
228
                   ->disableOriginalConstructor()
229
                   ->getMock();
230
231
        $reflection = new \ReflectionClass(get_class($pq));
232
        $method = $reflection->getMethod('addOrderedColumns');
233
        $method->setAccessible(true);
234
        $method->invoke($pq, $qb, ['o.id1', 'o.id2']);
235
236
        $dqlPart = $qb->getDqlPart('select');
237
        $this->assertCount(1, $dqlPart);
238
        /** @var Select $select */
239
        $select = $dqlPart[0];
240
        $this->assertInstanceOf('Doctrine\ORM\Query\Expr\Select', $select);
241
        $this->assertEquals('IDENTITY(o.id1) as id1, IDENTITY(o.id2) as id2', $select->getParts()[0]);
242
    }
243
}
244