Passed
Pull Request — master (#19)
by James
05:53
created

testDoctrineWithMappingDriverChainMissingNamespace()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace GraphQLTests\Doctrine;
6
7
use DateTime;
8
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain;
9
use Doctrine\ORM\Tools\SchemaValidator;
10
use GraphQL\Type\Definition\BooleanType;
11
use GraphQL\Type\Definition\ObjectType;
12
use GraphQL\Type\Definition\Type;
13
use GraphQL\Type\Schema;
14
use GraphQLTests\Doctrine\Blog\Model\Post;
15
use GraphQLTests\Doctrine\Blog\Types\CustomType;
16
use GraphQLTests\Doctrine\Blog\Types\DateTimeType;
17
use GraphQLTests\Doctrine\Blog\Types\PostStatusType;
18
use stdClass;
19
20
final class TypesTest extends \PHPUnit\Framework\TestCase
21
{
22
    use TypesTrait;
23
24
    public function testBlogMapping(): void
25
    {
26
        $validator = new SchemaValidator($this->entityManager);
27
        $errors = $validator->validateMapping();
28
29
        self::assertEmpty($errors, 'doctrine annotations should be valid');
30
    }
31
32
    public function testGraphQLSchemaFromDocumentationMustBeValid(): void
33
    {
34
        $types = $this->types;
35
        $schema = new Schema([
36
            'query' => new ObjectType([
37
                'name' => 'query',
38
                'fields' => [
39
                    'posts' => [
40
                        'type' => Type::listOf($types->getOutput(Post::class)), // Use automated ObjectType for output
41
                        'args' => [
42
                            [
43
                                'name' => 'filter',
44
                                'type' => $types->getFilter(Post::class), // Use automated filtering options
45
                            ],
46
                            [
47
                                'name' => 'sorting',
48
                                'type' => $types->getSorting(Post::class), // Use automated sorting options
49
                            ],
50
                        ],
51
                        'resolve' => function ($root, $args) use ($types): void {
52
                            $queryBuilder = $types->createFilteredQueryBuilder(Post::class, $args['filter'] ?? [], $args['sorting'] ?? []);
0 ignored issues
show
Unused Code introduced by
The assignment to $queryBuilder is dead and can be removed.
Loading history...
53
54
                        // execute query...
55
                        },
56
                    ],
57
                ],
58
            ]),
59
            'mutation' => new ObjectType([
60
                'name' => 'mutation',
61
                'fields' => [
62
                    'createPost' => [
63
                        'type' => Type::nonNull($types->getOutput(Post::class)),
64
                        'args' => [
65
                            'input' => Type::nonNull($types->getInput(Post::class)), // Use automated InputObjectType for input
66
                        ],
67
                        'resolve' => function ($root, $args): void {
2 ignored issues
show
Unused Code introduced by
The parameter $root is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

67
                        'resolve' => function (/** @scrutinizer ignore-unused */ $root, $args): void {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

67
                        'resolve' => function ($root, /** @scrutinizer ignore-unused */ $args): void {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
68
                            // create new post and flush...
69
                        },
70
                    ],
71
                    'updatePost' => [
72
                        'type' => Type::nonNull($types->getOutput(Post::class)),
73
                        'args' => [
74
                            'id' => Type::nonNull(Type::id()), // Use standard API when needed
75
                            'input' => $types->getPartialInput(Post::class),  // Use automated InputObjectType for partial input for updates
76
                        ],
77
                        'resolve' => function ($root, $args): void {
2 ignored issues
show
Unused Code introduced by
The parameter $args is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

77
                        'resolve' => function ($root, /** @scrutinizer ignore-unused */ $args): void {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $root is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

77
                        'resolve' => function (/** @scrutinizer ignore-unused */ $root, $args): void {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
78
                            // update existing post and flush...
79
                        },
80
                    ],
81
                ],
82
            ]),
83
        ]);
84
85
        $schema->assertValid();
86
        self::assertTrue(true, 'passed validation successfully');
87
    }
88
89
    public function testCanGetUserDefinedScalarTypes(): void
90
    {
91
        $bool = $this->types->get(BooleanType::class);
92
        $status = $this->types->get(PostStatusType::class);
93
94
        self::assertInstanceOf(BooleanType::class, $bool, 'must be a instance of bool');
95
        self::assertInstanceOf(PostStatusType::class, $status, 'must be an instance of post status');
96
97
        self::assertSame($bool, $this->types->get(BooleanType::class), 'must returns the same instance of bool');
98
        self::assertSame($status, $this->types->get(PostStatusType::class), 'must returns the same instance of post status');
99
    }
100
101
    public function testCanGetUserMappedTypes(): void
102
    {
103
        $type = $this->types->get(stdClass::class);
104
105
        self::assertInstanceOf(CustomType::class, $type, 'must be a instance of CustomType');
106
        self::assertSame($type, $this->types->get('customName'));
107
    }
108
109
    public function testCanGetMappedTypesEitherByMappedPhpClassOrDirectTypeClass(): void
110
    {
111
        $viaPhp = $this->types->get(DateTime::class);
112
        $viaType = $this->types->get(DateTimeType::class);
113
        self::assertSame($viaPhp, $viaType);
114
    }
115
116
    public function testDoctrineWithMappingDriverChainUsingDefault(): void
117
    {
118
        // Replace annotation driver with a driver chain
119
        $config = $this->entityManager->getConfiguration();
120
        $chain = new MappingDriverChain();
121
        $chain->setDefaultDriver($config->getMetadataDriverImpl());
122
        $config->setMetadataDriverImpl($chain);
123
124
        $type = $this->types->getOutput(Post::class);
125
        self::assertNotEmpty($type->getFields());
126
    }
127
128
    public function testDoctrineWithMappingDriverChainUsingNamespace(): void
129
    {
130
        // Replace annotation driver with a driver chain
131
        $config = $this->entityManager->getConfiguration();
132
        $chain = new MappingDriverChain();
133
        $chain->addDriver($config->getMetadataDriverImpl(), 'GraphQLTests\Doctrine\Blog\Model');
134
        $config->setMetadataDriverImpl($chain);
135
136
        $type = $this->types->getOutput(Post::class);
137
        self::assertNotEmpty($type->getFields());
138
    }
139
140
    public function testDoctrineWithMappingDriverChainMissingNamespace() {
141
        $config = $this->entityManager->getConfiguration();
142
        $chain = new MappingDriverChain();
143
        $type = $this->types->getOutput(Post::class);
144
145
        $config->setMetadataDriverImpl($chain);
146
        $this->expectExceptionMessage('graphql-doctrine requires GraphQLTests\Doctrine\Blog\Model\Post entity to be configured with a `Doctrine\Common\Persistence\Mapping\Driver\AnnotationDriver`.');
147
        $type->getFields();
148
    }
149
150
    public function testNonRegisteredCustomTypeMustThrow(): void
151
    {
152
        $this->expectExceptionMessage('No type registered with key `foo`. Either correct the usage, or register it in your custom types container when instantiating `GraphQL\Doctrine\Types`');
153
        $this->types->get('foo');
154
    }
155
156
    public function testHas(): void
157
    {
158
        $this->assertTrue($this->types->has(stdClass::class), 'should have custom registered key');
159
        $this->assertFalse($this->types->has('non-existing'), 'should not have non-existing things');
160
161
        $this->types->get(stdClass::class);
162
        $this->assertTrue($this->types->has('customName'), 'should have custom registered type by its name, even if custom key was different, once type is created');
163
    }
164
}
165