Completed
Pull Request — 3.x (#730)
by
unknown
01:37
created

ProxyQueryTest   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 190
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 10
c 2
b 0
f 0
lcom 1
cbo 11
dl 0
loc 190
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A setUpBeforeClass() 0 6 2
A setUp() 0 19 3
A tearDown() 0 4 1
A dataGetFixedQueryBuilder() 0 9 1
B testGetFixedQueryBuilder() 0 81 1
B testAddOrderedColumns() 0 24 1
B testSetHint() 0 24 1
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\SqlWalker;
19
use Doctrine\ORM\Tools\SchemaTool;
20
use Sonata\DoctrineORMAdminBundle\Datagrid\ProxyQuery;
21
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\DoctrineType\UuidType;
22
use Sonata\DoctrineORMAdminBundle\Tests\Fixtures\Util\NonIntegerIdentifierTestClass;
23
use Sonata\DoctrineORMAdminBundle\Tests\Helpers\PHPUnit_Framework_TestCase;
24
use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper;
25
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity;
26
27
class ProxyQueryTest extends PHPUnit_Framework_TestCase
28
{
29
    const DOUBLE_NAME_CLASS = 'Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity';
30
31
    /**
32
     * @var EntityManager
33
     */
34
    private $em;
35
36
    public static function setUpBeforeClass()
37
    {
38
        if (!Type::hasType('uuid')) {
39
            Type::addType('uuid', 'Sonata\DoctrineORMAdminBundle\Tests\Fixtures\DoctrineType\UuidType');
40
        }
41
    }
42
43
    protected function setUp()
44
    {
45
        $this->em = DoctrineTestHelper::createTestEntityManager();
46
47
        $schemaTool = new SchemaTool($this->em);
48
        $classes = array(
49
            $this->em->getClassMetadata(self::DOUBLE_NAME_CLASS),
50
        );
51
52
        try {
53
            $schemaTool->dropSchema($classes);
54
        } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
55
        }
56
57
        try {
58
            $schemaTool->createSchema($classes);
59
        } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
60
        }
61
    }
62
63
    protected function tearDown()
64
    {
65
        $this->em = null;
66
    }
67
68
    public function dataGetFixedQueryBuilder()
69
    {
70
        return array(
71
            array('aaa', 'bbb', 'id', 'id_idx', 33, Type::INTEGER),
72
            array('aaa', 'bbb', 'associatedId', 'associatedId_idx', 33, null),
73
            array('aaa', 'bbb', 'id.value', 'id_value_idx', 33, Type::INTEGER),
74
            array('aaa', 'bbb', 'id.uuid', 'id_uuid_idx', new NonIntegerIdentifierTestClass('80fb6f91-bba1-4d35-b3d4-e06b24494e85'), UuidType::NAME),
75
        );
76
    }
77
78
    /**
79
     * @dataProvider dataGetFixedQueryBuilder
80
     *
81
     * @param $class
82
     * @param $alias
83
     * @param $id
84
     */
85
    public function testGetFixedQueryBuilder($class, $alias, $id, $expectedId, $value, $identifierType)
86
    {
87
        $meta = $this->createMock('Doctrine\ORM\Mapping\ClassMetadataInfo');
88
        $meta->expects($this->any())
89
            ->method('getIdentifierFieldNames')
90
            ->willReturn(array($id));
91
        $meta->expects($this->any())
92
            ->method('getTypeOfField')
93
            ->willReturn($identifierType);
94
95
        $mf = $this->createMock('Doctrine\ORM\Mapping\ClassMetadataFactory');
96
        $mf->expects($this->any())
97
            ->method('getMetadataFor')
98
            ->with($this->equalTo($class))
99
            ->willReturn($meta);
100
101
        $platform = $this->createMock('Doctrine\DBAL\Platforms\PostgreSqlPlatform');
102
103
        $conn = $this->createMock('Doctrine\DBAL\Connection');
104
        $conn->expects($this->any())
105
            ->method('getDatabasePlatform')
106
            ->willReturn($platform);
107
108
        $em = $this->createMock('Doctrine\ORM\EntityManager');
109
        $em->expects($this->any())
110
            ->method('getMetadataFactory')
111
            ->willReturn($mf);
112
        $em->expects($this->any())
113
            ->method('getConnection')
114
            ->willReturn($conn);
115
116
        // NEXT MAJOR: Replace this when dropping PHP < 5.6
117
        // $q = $this->createMock('PDOStatement');
118
        $q = $this->getMockBuilder('stdClass')
119
            ->setMethods(array('execute'))
120
            ->getMock();
121
        $q->expects($this->any())
122
            ->method('execute')
123
            ->willReturn(array(array($id => $value)));
124
125
        $qb = $this->getMockBuilder('Doctrine\ORM\QueryBuilder')
126
            ->setConstructorArgs(array($em))
127
            ->getMock();
128
        $qb->expects($this->any())
129
            ->method('getEntityManager')
130
            ->willReturn($em);
131
        $qb->expects($this->any())
132
            ->method('getQuery')
133
            ->willReturn($q);
134
        $qb->expects($this->once())
135
            ->method('setParameter')
136
            ->with($this->equalTo($expectedId), $this->equalTo(array($value)));
137
        $qb->expects($this->any())
138
            ->method('getDQLPart')
139
            ->will($this->returnCallBack(function ($part) use ($class, $alias) {
140
                $parts = array(
141
                    'from' => array(new From($class, $alias)),
142
                    'orderBy' => array(new OrderBy('whatever', 'DESC')),
143
                );
144
145
                return $parts[$part];
146
            }));
147
        $qb->expects($this->once())
148
            ->method('addOrderBy')
149
            ->with("$alias.$id", null);
150
        $qb->expects($this->once())
151
            ->method('getRootEntities')
152
            ->willReturn(array($class));
153
        $qb->expects($this->exactly(2))
154
            ->method('getRootAliases')
155
            ->willReturn(array($alias));
156
157
        $pq = $this->getMockBuilder('Sonata\DoctrineORMAdminBundle\Datagrid\ProxyQuery')
158
            ->setConstructorArgs(array($qb))
159
            ->setMethods(array('a'))
160
            ->getMock();
161
162
        /* Work */
163
164
        $pq->execute();
165
    }
166
167
    public function testAddOrderedColumns()
168
    {
169
        $qb = $this->em->createQueryBuilder()
170
                       ->select('o.id')
171
                       ->distinct()
172
                       ->from(self::DOUBLE_NAME_CLASS, 'o')
173
                       ->orderBy('o.name', 'ASC')
174
                       ->addOrderBy('o.name2', 'DESC');
175
176
        $pq = $this->getMockBuilder('Sonata\DoctrineORMAdminBundle\Datagrid\ProxyQuery')
177
                   ->disableOriginalConstructor()
178
                   ->getMock();
179
180
        $reflection = new \ReflectionClass(get_class($pq));
181
        $method = $reflection->getMethod('addOrderedColumns');
182
        $method->setAccessible(true);
183
        $method->invoke($pq, $qb);
184
185
        $dqlPart = $qb->getDqlPart('select');
186
        $this->assertCount(3, $dqlPart);
187
        $this->assertEquals('o.id', $dqlPart[0]);
188
        $this->assertEquals('o.name', $dqlPart[1]);
189
        $this->assertEquals('o.name2', $dqlPart[2]);
190
    }
191
192
    public function testSetHint()
193
    {
194
        $entity1 = new DoubleNameEntity(1, 'Foo', null);
195
        $entity2 = new DoubleNameEntity(2, 'Bar', null);
196
197
        $this->em->persist($entity1);
198
        $this->em->persist($entity2);
199
        $this->em->flush();
200
201
        $qb = $this->em->createQueryBuilder()
202
                       ->select('o.id')
203
                       ->from(self::DOUBLE_NAME_CLASS, 'o');
204
205
        $pq = new ProxyQuery($qb);
206
        $pq->setHint(
207
            \Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER,
208
            'Sonata\DoctrineORMAdminBundle\Tests\Datagrid\TestWalker'
209
        );
210
        $pq->setHint('hint', 'value');
211
212
        $result = $pq->execute();
213
214
        $this->assertEquals(2, $result[0]['id']);
215
    }
216
}
217
218
class TestWalker extends SqlWalker
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
219
{
220
    public function walkOrderByClause($orderByClause)
221
    {
222
        $sql = parent::walkOrderByClause($orderByClause);
223
224
        return str_replace(' ASC', ' DESC', $sql);
225
    }
226
}
227