Issues (131)

tests/Functional/ORMModelFactoryTest.php (9 issues)

1
<?php
2
3
namespace Zenstruck\Foundry\Tests\Functional;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use Zenstruck\Foundry\Tests\Fixtures\Entity\Category;
7
use Zenstruck\Foundry\Tests\Fixtures\Factories\AddressFactory;
8
use Zenstruck\Foundry\Tests\Fixtures\Factories\CategoryFactory;
9
use Zenstruck\Foundry\Tests\Fixtures\Factories\CommentFactory;
10
use Zenstruck\Foundry\Tests\Fixtures\Factories\ContactFactory;
11
use Zenstruck\Foundry\Tests\Fixtures\Factories\PostFactory;
12
use Zenstruck\Foundry\Tests\Fixtures\Factories\PostFactoryWithInvalidInitialize;
13
use Zenstruck\Foundry\Tests\Fixtures\Factories\PostFactoryWithNullInitialize;
14
use Zenstruck\Foundry\Tests\Fixtures\Factories\PostFactoryWithValidInitialize;
15
use Zenstruck\Foundry\Tests\Fixtures\Factories\TagFactory;
16
use Zenstruck\Foundry\Tests\Fixtures\Factories\UserFactory;
17
18
/**
19
 * @author Kevin Bond <[email protected]>
20
 */
21
final class ORMModelFactoryTest extends ModelFactoryTest
22
{
23
    protected function setUp(): void
24
    {
25
        if (false === \getenv('DATABASE_URL')) {
26
            self::markTestSkipped('doctrine/orm not enabled.');
27
        }
28
    }
29
30
    /**
31
     * @test
32
     */
33
    public function can_override_initialize(): void
34
    {
35
        $this->assertFalse(PostFactory::createOne()->isPublished());
0 ignored issues
show
The method isPublished() does not exist on Zenstruck\Foundry\Proxy. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

35
        $this->assertFalse(PostFactory::createOne()->/** @scrutinizer ignore-call */ isPublished());
Loading history...
36
        $this->assertTrue(PostFactoryWithValidInitialize::createOne()->isPublished());
37
    }
38
39
    /**
40
     * @test
41
     */
42
    public function initialize_must_return_an_instance_of_the_current_factory(): void
43
    {
44
        $this->expectException(\TypeError::class);
45
        $this->expectExceptionMessage(\sprintf('"%1$s::initialize()" must return an instance of "%1$s".', PostFactoryWithInvalidInitialize::class));
46
47
        PostFactoryWithInvalidInitialize::new();
48
    }
49
50
    /**
51
     * @test
52
     */
53
    public function initialize_must_return_a_value(): void
54
    {
55
        $this->expectException(\TypeError::class);
56
        $this->expectExceptionMessage(\sprintf('"%1$s::initialize()" must return an instance of "%1$s".', PostFactoryWithNullInitialize::class));
57
58
        PostFactoryWithNullInitialize::new();
59
    }
60
61
    /**
62
     * @test
63
     */
64
    public function one_to_many_with_nested_collection_relationship(): void
65
    {
66
        $post = PostFactory::createOne([
67
            'comments' => CommentFactory::new()->many(4),
68
        ]);
69
70
        $this->assertCount(4, $post->getComments());
0 ignored issues
show
The method getComments() does not exist on Zenstruck\Foundry\Proxy. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

70
        $this->assertCount(4, $post->/** @scrutinizer ignore-call */ getComments());
Loading history...
71
        UserFactory::assert()->count(4);
72
        CommentFactory::assert()->count(4);
73
        PostFactory::assert()->count(1);
74
    }
75
76
    /**
77
     * @test
78
     */
79
    public function create_multiple_one_to_many_with_nested_collection_relationship(): void
80
    {
81
        $user = UserFactory::createOne();
82
        $posts = PostFactory::createMany(2, [
83
            'comments' => CommentFactory::new(['user' => $user])->many(4),
84
        ]);
85
86
        $this->assertCount(4, $posts[0]->getComments());
87
        $this->assertCount(4, $posts[1]->getComments());
88
        UserFactory::assert()->count(1);
89
        CommentFactory::assert()->count(8);
90
        PostFactory::assert()->count(2);
91
    }
92
93
    /**
94
     * @test
95
     */
96
    public function many_to_many_with_nested_collection_relationship(): void
97
    {
98
        $post = PostFactory::createOne([
99
            'tags' => TagFactory::new()->many(3),
100
        ]);
101
102
        $this->assertCount(3, $post->getTags());
0 ignored issues
show
The method getTags() does not exist on Zenstruck\Foundry\Proxy. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

102
        $this->assertCount(3, $post->/** @scrutinizer ignore-call */ getTags());
Loading history...
103
        TagFactory::assert()->count(5); // 3 created by this test and 2 in global state
104
        PostFactory::assert()->count(1);
105
    }
106
107
    /**
108
     * @test
109
     */
110
    public function inverse_many_to_many_with_nested_collection_relationship(): void
111
    {
112
        $tag = TagFactory::createOne([
113
            'posts' => PostFactory::new()->many(3),
114
        ]);
115
116
        $this->assertCount(3, $tag->getPosts());
0 ignored issues
show
The method getPosts() does not exist on Zenstruck\Foundry\Proxy. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

116
        $this->assertCount(3, $tag->/** @scrutinizer ignore-call */ getPosts());
Loading history...
117
        TagFactory::assert()->count(3); // 1 created by this test and 2 in global state
118
        PostFactory::assert()->count(3);
119
    }
120
121
    /**
122
     * @test
123
     */
124
    public function create_multiple_many_to_many_with_nested_collection_relationship(): void
125
    {
126
        $posts = PostFactory::createMany(2, [
127
            'tags' => TagFactory::new()->many(3),
128
        ]);
129
130
        $this->assertCount(3, $posts[0]->getTags());
131
        $this->assertCount(3, $posts[1]->getTags());
132
        TagFactory::assert()->count(8); // 6 created by this test and 2 in global state
133
        PostFactory::assert()->count(2);
134
    }
135
136
    /**
137
     * @test
138
     */
139
    public function unpersisted_one_to_many_with_nested_collection_relationship(): void
140
    {
141
        $post = PostFactory::new()->withoutPersisting()->create([
142
            'comments' => CommentFactory::new()->many(4),
143
        ]);
144
145
        $this->assertCount(4, $post->getComments());
146
        UserFactory::assert()->empty();
147
        CommentFactory::assert()->empty();
148
        PostFactory::assert()->empty();
149
    }
150
151
    /**
152
     * @test
153
     */
154
    public function unpersisted_many_to_many_with_nested_collection_relationship(): void
155
    {
156
        $post = PostFactory::new()->withoutPersisting()->create([
157
            'tags' => TagFactory::new()->many(3),
158
        ]);
159
160
        $this->assertCount(3, $post->getTags());
161
        TagFactory::assert()->count(2); // 2 created in global state
162
        PostFactory::assert()->empty();
163
    }
164
165
    /**
166
     * @test
167
     * @dataProvider dataProvider
168
     */
169
    public function can_use_model_factories_in_a_data_provider(PostFactory $factory, bool $published): void
170
    {
171
        $post = $factory->create();
172
173
        $post->assertPersisted();
174
        $this->assertSame($published, $post->isPublished());
175
    }
176
177
    public static function dataProvider(): array
178
    {
179
        return [
180
            [PostFactory::new(), false],
181
            [PostFactory::new()->published(), true],
0 ignored issues
show
The method published() does not exist on Zenstruck\Foundry\ModelFactory. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

181
            [PostFactory::new()->/** @scrutinizer ignore-call */ published(), true],
Loading history...
182
        ];
183
    }
184
185
    /**
186
     * @test
187
     */
188
    public function many_to_one_unmanaged_entity(): void
189
    {
190
        $category = CategoryFactory::createOne(['name' => 'My Category']);
191
192
        self::container()->get(EntityManagerInterface::class)->clear();
193
194
        $post = PostFactory::createOne(['category' => $category]);
195
196
        $this->assertSame('My Category', $post->getCategory()->getName());
0 ignored issues
show
The method getCategory() does not exist on Zenstruck\Foundry\Proxy. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

196
        $this->assertSame('My Category', $post->/** @scrutinizer ignore-call */ getCategory()->getName());
Loading history...
197
    }
198
199
    /**
200
     * @test
201
     */
202
    public function many_to_one_unmanaged_raw_entity(): void
203
    {
204
        $category = CategoryFactory::createOne(['name' => 'My Category'])->object();
205
206
        self::container()->get(EntityManagerInterface::class)->clear();
207
208
        $post = PostFactory::createOne(['category' => $category]);
209
210
        $this->assertSame('My Category', $post->getCategory()->getName());
211
    }
212
213
    /**
214
     * @test
215
     */
216
    public function factory_with_embeddable(): void
217
    {
218
        ContactFactory::repository()->assert()->empty();
219
220
        $object = ContactFactory::createOne();
221
222
        ContactFactory::repository()->assert()->count(1);
223
        $this->assertSame('Sally', $object->getName());
0 ignored issues
show
The method getName() does not exist on Zenstruck\Foundry\Proxy. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

223
        $this->assertSame('Sally', $object->/** @scrutinizer ignore-call */ getName());
Loading history...
224
        $this->assertSame('Some address', $object->getAddress()->getValue());
0 ignored issues
show
The method getAddress() does not exist on Zenstruck\Foundry\Proxy. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

224
        $this->assertSame('Some address', $object->/** @scrutinizer ignore-call */ getAddress()->getValue());
Loading history...
225
    }
226
227
    /**
228
     * @test
229
     */
230
    public function embeddables_are_never_persisted(): void
231
    {
232
        $object1 = AddressFactory::createOne();
233
        $object2 = AddressFactory::createOne(['value' => 'another address']);
234
235
        $this->assertSame('Some address', $object1->getValue());
0 ignored issues
show
The method getValue() does not exist on Zenstruck\Foundry\Proxy. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

235
        $this->assertSame('Some address', $object1->/** @scrutinizer ignore-call */ getValue());
Loading history...
236
        $this->assertSame('another address', $object2->getValue());
237
    }
238
239
    protected function categoryClass(): string
240
    {
241
        return Category::class;
242
    }
243
244
    protected function categoryFactoryClass(): string
245
    {
246
        return CategoryFactory::class;
247
    }
248
}
249