Skip to content

Commit 0d9d1fe

Browse files
committed
[Tests] Added unit tests for strategies
1 parent 9ba20d7 commit 0d9d1fe

File tree

5 files changed

+365
-0
lines changed

5 files changed

+365
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Tests\CorePersistence\Gateway;
10+
11+
use Doctrine\DBAL\Connection;
12+
use Doctrine\DBAL\Platforms\AbstractPlatform;
13+
use Doctrine\DBAL\Query\Expression\ExpressionBuilder;
14+
use Ibexa\Contracts\CorePersistence\Gateway\DoctrineRelationship;
15+
use Ibexa\Contracts\CorePersistence\Gateway\DoctrineSchemaMetadata;
16+
use Ibexa\Tests\CorePersistence\Stub\RelationshipClass;
17+
use PHPUnit\Framework\TestCase;
18+
19+
abstract class BaseRelationshipTypeStrategyTestCase extends TestCase
20+
{
21+
/** @var \Doctrine\DBAL\Connection&\PHPUnit\Framework\MockObject\MockObject */
22+
protected Connection $connection;
23+
24+
protected function setUp(): void
25+
{
26+
$this->connection = $this->createMock(Connection::class);
27+
$this->connection
28+
->method('getExpressionBuilder')
29+
->willReturn(new ExpressionBuilder($this->connection));
30+
31+
$platform = $this->getMockBuilder(AbstractPlatform::class)
32+
->getMockForAbstractClass();
33+
34+
$this->connection
35+
->method('getDatabasePlatform')
36+
->willReturn($platform);
37+
}
38+
39+
protected function createDoctrineRelationship(): DoctrineRelationship
40+
{
41+
return new DoctrineRelationship(
42+
RelationshipClass::class,
43+
DoctrineRelationship::JOIN_TYPE_JOINED,
44+
'related_class_id_column',
45+
'foreign_key_column'
46+
);
47+
}
48+
49+
protected function createDoctrineSchemaMetadata(): DoctrineSchemaMetadata
50+
{
51+
return new DoctrineSchemaMetadata(
52+
$this->connection,
53+
RelationshipClass::class,
54+
'test_alias',
55+
['related_class_id_column' => 'integer'],
56+
['foreign_key_column' => 'integer']
57+
);
58+
}
59+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Tests\CorePersistence\Gateway;
10+
11+
use Doctrine\Common\Collections\Expr\Comparison;
12+
use Doctrine\DBAL\Query\QueryBuilder;
13+
use Ibexa\CorePersistence\Gateway\JoinedRelationshipTypeStrategy;
14+
15+
/**
16+
* @covers \Ibexa\CorePersistence\Gateway\JoinedRelationshipTypeStrategy
17+
*/
18+
final class JoinedRelationshipTypeStrategyTest extends BaseRelationshipTypeStrategyTestCase
19+
{
20+
private JoinedRelationshipTypeStrategy $strategy;
21+
22+
protected function setUp(): void
23+
{
24+
parent::setUp();
25+
26+
$this->strategy = new JoinedRelationshipTypeStrategy();
27+
}
28+
29+
public function testHandleRelationshipType(): void
30+
{
31+
$queryBuilder = new QueryBuilder($this->connection);
32+
33+
$this->strategy->handleRelationshipType(
34+
$queryBuilder,
35+
$this->createDoctrineRelationship(),
36+
'root_alias',
37+
'from_table',
38+
'to_table'
39+
);
40+
41+
self::assertEmpty($queryBuilder->getQueryPart('select'));
42+
self::assertEmpty($queryBuilder->getQueryPart('from'));
43+
self::assertEmpty($queryBuilder->getQueryPart('where'));
44+
self::assertSame(
45+
[
46+
'from_table' => [
47+
[
48+
'joinType' => 'left',
49+
'joinTable' => 'to_table',
50+
'joinAlias' => 'to_table',
51+
'joinCondition' => 'from_table.related_class_id_column = to_table.foreign_key_column',
52+
],
53+
],
54+
],
55+
$queryBuilder->getQueryPart('join')
56+
);
57+
}
58+
59+
public function testHandleRelationshipTypeQuery(): void
60+
{
61+
$relationshipQuery = $this->strategy->handleRelationshipTypeQuery(
62+
$this->createDoctrineSchemaMetadata(),
63+
$this->createDoctrineRelationship(),
64+
'related_class_id_column',
65+
new Comparison(
66+
'related_class_id_column',
67+
Comparison::EQ,
68+
'value'
69+
),
70+
new QueryBuilder($this->connection),
71+
[]
72+
);
73+
74+
$parameter = $relationshipQuery->getParameter();
75+
self::assertSame('related_class_id_column_0', $parameter->getName());
76+
self::assertSame(1, $parameter->getType());
77+
self::assertSame('value', $parameter->getValue());
78+
79+
$queryBuilder = $relationshipQuery->getQueryBuilder();
80+
81+
self::assertEmpty($queryBuilder->getQueryPart('select'));
82+
self::assertEmpty($queryBuilder->getQueryPart('from'));
83+
self::assertEmpty($queryBuilder->getQueryPart('where'));
84+
self::assertEmpty($queryBuilder->getQueryPart('join'));
85+
}
86+
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Tests\CorePersistence\Gateway;
10+
11+
use Doctrine\Common\Collections\Expr\Comparison;
12+
use Doctrine\DBAL\Connection;
13+
use Doctrine\DBAL\Query\QueryBuilder;
14+
use Ibexa\Contracts\CorePersistence\Exception\RuntimeMappingException;
15+
use Ibexa\Contracts\CorePersistence\Gateway\DoctrineRelationshipInterface;
16+
use Ibexa\Contracts\CorePersistence\Gateway\DoctrineSchemaMetadataInterface;
17+
use Ibexa\CorePersistence\Gateway\RelationshipTypeStrategyRegistry;
18+
use Ibexa\Tests\CorePersistence\Stub\RelationshipClass;
19+
use PHPUnit\Framework\TestCase;
20+
21+
/**
22+
* @covers \Ibexa\CorePersistence\Gateway\RelationshipTypeStrategyRegistry
23+
*/
24+
final class RelationshipTypeStrategyRegistryTest extends TestCase
25+
{
26+
private RelationshipTypeStrategyRegistry $registry;
27+
28+
protected function setUp(): void
29+
{
30+
$this->registry = new RelationshipTypeStrategyRegistry();
31+
}
32+
33+
public function testHandleRelationshipTypeThrowsRuntimeMappingException(): void
34+
{
35+
$this->expectException(RuntimeMappingException::class);
36+
$this->expectExceptionMessage('Unhandled relationship metadata. Expected one of "Ibexa\Contracts\CorePersistence\Gateway\DoctrineRelationship", "Ibexa\Contracts\CorePersistence\Gateway\DoctrineOneToManyRelationship"');
37+
38+
$this->registry->handleRelationshipType(
39+
new QueryBuilder($this->createMock(Connection::class)),
40+
$this->createInvalidRelationshipType(),
41+
'root_table_alias',
42+
'from_table',
43+
'to_table'
44+
);
45+
}
46+
47+
public function testHandleRelationshipTypeQueryThrowsRuntimeMappingException(): void
48+
{
49+
$this->expectException(RuntimeMappingException::class);
50+
$this->expectExceptionMessage('Unhandled relationship metadata. Expected one of "Ibexa\Contracts\CorePersistence\Gateway\DoctrineRelationship", "Ibexa\Contracts\CorePersistence\Gateway\DoctrineOneToManyRelationship". Received "Ibexa\Contracts\CorePersistence\Gateway\DoctrineRelationshipInterface@anonymous');
51+
52+
$this->registry->handleRelationshipTypeQuery(
53+
$this->createMock(DoctrineSchemaMetadataInterface::class),
54+
$this->createInvalidRelationshipType(),
55+
'field',
56+
new Comparison(
57+
'related_class_id_column',
58+
Comparison::EQ,
59+
'value'
60+
),
61+
new QueryBuilder($this->createMock(Connection::class)),
62+
[]
63+
);
64+
}
65+
66+
private function createInvalidRelationshipType(): DoctrineRelationshipInterface
67+
{
68+
return new class() implements DoctrineRelationshipInterface {
69+
public function getRelationshipClass(): string
70+
{
71+
return RelationshipClass::class;
72+
}
73+
74+
public function getRelatedClassIdColumn(): string
75+
{
76+
return 'related_class_id_column';
77+
}
78+
79+
public function getForeignProperty(): string
80+
{
81+
return 'foreign_property';
82+
}
83+
84+
public function getForeignKeyColumn(): string
85+
{
86+
return 'foreign_key_column';
87+
}
88+
89+
public function setJoinType(string $joinType): void
90+
{
91+
// Implementation here...
92+
}
93+
94+
public function getJoinType(): string
95+
{
96+
return 'join_type';
97+
}
98+
};
99+
}
100+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Tests\CorePersistence\Gateway;
10+
11+
use Doctrine\Common\Collections\Expr\Comparison;
12+
use Doctrine\DBAL\Query\Expression\CompositeExpression;
13+
use Doctrine\DBAL\Query\QueryBuilder;
14+
use Ibexa\CorePersistence\Gateway\SubSelectRelationshipTypeStrategy;
15+
16+
/**
17+
* @covers \Ibexa\CorePersistence\Gateway\SubSelectRelationshipTypeStrategy
18+
*/
19+
final class SubSelectRelationshipTypeStrategyTest extends BaseRelationshipTypeStrategyTestCase
20+
{
21+
private SubSelectRelationshipTypeStrategy $strategy;
22+
23+
protected function setUp(): void
24+
{
25+
parent::setUp();
26+
27+
$this->strategy = new SubSelectRelationshipTypeStrategy();
28+
}
29+
30+
public function testHandleRelationshipType(): void
31+
{
32+
$queryBuilder = new QueryBuilder($this->connection);
33+
34+
$this->strategy->handleRelationshipType(
35+
$queryBuilder,
36+
$this->createDoctrineRelationship(),
37+
'root_alias',
38+
'from_table',
39+
'to_table'
40+
);
41+
42+
self::assertSame(
43+
['to_table.foreign_key_column'],
44+
$queryBuilder->getQueryPart('select')
45+
);
46+
self::assertSame(
47+
[
48+
[
49+
'table' => 'to_table',
50+
'alias' => null,
51+
],
52+
],
53+
$queryBuilder->getQueryPart('from')
54+
);
55+
self::assertEmpty($queryBuilder->getQueryPart('where'));
56+
self::assertSame(
57+
[
58+
'from_table' => [
59+
[
60+
'joinType' => 'inner',
61+
'joinTable' => 'to_table',
62+
'joinAlias' => 'to_table',
63+
'joinCondition' => 'from_table.related_class_id_column = to_table.foreign_key_column',
64+
],
65+
],
66+
],
67+
$queryBuilder->getQueryPart('join')
68+
);
69+
}
70+
71+
public function testHandleRelationshipTypeQuery(): void
72+
{
73+
$relationshipQuery = $this->strategy->handleRelationshipTypeQuery(
74+
$this->createDoctrineSchemaMetadata(),
75+
$this->createDoctrineRelationship(),
76+
'related_class_id_column',
77+
new Comparison(
78+
'related_class_id_column',
79+
Comparison::EQ,
80+
'value'
81+
),
82+
new QueryBuilder($this->connection),
83+
[]
84+
);
85+
86+
$parameter = $relationshipQuery->getParameter();
87+
self::assertSame('related_class_id_column_0', $parameter->getName());
88+
self::assertSame(1, $parameter->getType());
89+
self::assertSame('value', $parameter->getValue());
90+
91+
$queryBuilder = $relationshipQuery->getQueryBuilder();
92+
93+
self::assertEmpty($queryBuilder->getQueryPart('select'));
94+
self::assertEmpty($queryBuilder->getQueryPart('from'));
95+
self::assertEquals(
96+
new CompositeExpression(
97+
CompositeExpression::TYPE_AND,
98+
[
99+
'test_alias.related_class_id_column IN (:related_class_id_column_0)',
100+
]
101+
),
102+
$queryBuilder->getQueryPart('where')
103+
);
104+
105+
self::assertEmpty($queryBuilder->getQueryPart('join'));
106+
}
107+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Tests\CorePersistence\Stub;
10+
11+
final class RelationshipClass
12+
{
13+
}

0 commit comments

Comments
 (0)