Passed
Pull Request — master (#185)
by Tobias
02:47
created

tests/Functional/RepositoryProxyTest.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace Zenstruck\Foundry\Tests\Functional;
4
5
use Doctrine\Common\Proxy\Proxy as DoctrineProxy;
6
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
7
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
8
use Zenstruck\Foundry\Proxy;
9
use Zenstruck\Foundry\Test\Factories;
10
use Zenstruck\Foundry\Test\ResetDatabase;
11
use Zenstruck\Foundry\Tests\Fixtures\Entity\Category;
12
use Zenstruck\Foundry\Tests\Fixtures\Entity\Post;
13
use Zenstruck\Foundry\Tests\Fixtures\Factories\CategoryFactory;
14
use Zenstruck\Foundry\Tests\Fixtures\Factories\PostFactory;
15
use function Zenstruck\Foundry\repository;
16
17
/**
18
 * @author Kevin Bond <[email protected]>
19
 */
20
final class RepositoryProxyTest extends KernelTestCase
21
{
22
    use ExpectDeprecationTrait, Factories, ResetDatabase;
23
24
    /**
25
     * @test
26
     */
27
    public function functions_calls_are_passed_to_underlying_repository(): void
28
    {
29
        $this->assertSame('from custom method', repository(Post::class)->customMethod());
30
    }
31
32
    /**
33
     * @test
34
     */
35
    public function assertions(): void
36
    {
37
        $repository = repository(Category::class);
38
39
        $repository->assert()->empty();
40
41
        CategoryFactory::createMany(2);
0 ignored issues
show
The method createMany() does not exist on Zenstruck\Foundry\Tests\...ctories\CategoryFactory. Since you implemented __callStatic, 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

41
        CategoryFactory::/** @scrutinizer ignore-call */ 
42
                         createMany(2);
Loading history...
42
43
        $repository->assert()->count(2);
44
        $repository->assert()->countGreaterThan(1);
45
        $repository->assert()->countGreaterThanOrEqual(2);
46
        $repository->assert()->countLessThan(3);
47
        $repository->assert()->countLessThanOrEqual(2);
48
    }
49
50
    /**
51
     * @test
52
     * @group legacy
53
     */
54
    public function assertions_legacy(): void
55
    {
56
        $repository = repository(Category::class);
57
58
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertEmpty() is deprecated, use RepositoryProxy::assert()->empty().');
59
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertCount() is deprecated, use RepositoryProxy::assert()->count().');
60
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertCountGreaterThan() is deprecated, use RepositoryProxy::assert()->countGreaterThan().');
61
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertCountGreaterThanOrEqual() is deprecated, use RepositoryProxy::assert()->countGreaterThanOrEqual().');
62
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertCountLessThan() is deprecated, use RepositoryProxy::assert()->countLessThan().');
63
        $this->expectDeprecation('Since zenstruck\foundry 1.8.0: Using RepositoryProxy::assertCountLessThanOrEqual() is deprecated, use RepositoryProxy::assert()->countLessThanOrEqual().');
64
65
        $repository->assertEmpty();
66
67
        CategoryFactory::createMany(2);
68
69
        $repository->assertCount(2);
70
        $repository->assertCountGreaterThan(1);
71
        $repository->assertCountGreaterThanOrEqual(2);
72
        $repository->assertCountLessThan(3);
73
        $repository->assertCountLessThanOrEqual(2);
74
    }
75
76
    /**
77
     * @test
78
     */
79
    public function can_fetch_objects(): void
80
    {
81
        $repository = repository(Category::class);
82
83
        CategoryFactory::createMany(2);
84
85
        $objects = $repository->findAll();
86
87
        $this->assertCount(2, $objects);
88
        $this->assertInstanceOf(Proxy::class, $objects[0]);
89
90
        $objects = $repository->findBy([]);
91
92
        $this->assertCount(2, $objects);
93
        $this->assertInstanceOf(Proxy::class, $objects[0]);
94
    }
95
96
    /**
97
     * @test
98
     */
99
    public function find_can_be_passed_proxy_or_object_or_array(): void
100
    {
101
        $repository = repository(Category::class);
102
        $proxy = CategoryFactory::createOne(['name' => 'foo']);
103
104
        $this->assertInstanceOf(Proxy::class, $repository->find($proxy));
105
        $this->assertInstanceOf(Proxy::class, $repository->find($proxy->object()));
106
        $this->assertInstanceOf(Proxy::class, $repository->find(['name' => 'foo']));
107
    }
108
109
    /**
110
     * @test
111
     */
112
    public function can_find_random_object(): void
113
    {
114
        CategoryFactory::createMany(5);
115
116
        $ids = [];
117
118
        while (5 !== \count(\array_unique($ids))) {
119
            $ids[] = repository(Category::class)->random()->getId();
120
        }
121
122
        $this->assertCount(5, \array_unique($ids));
123
    }
124
125
    /**
126
     * @test
127
     */
128
    public function at_least_one_object_must_exist_to_get_random_object(): void
129
    {
130
        $this->expectException(\RuntimeException::class);
131
        $this->expectExceptionMessage(\sprintf('At least 1 "%s" object(s) must have been persisted (0 persisted).', Category::class));
132
133
        repository(Category::class)->random();
134
    }
135
136
    /**
137
     * @test
138
     */
139
    public function can_find_random_set_of_objects(): void
140
    {
141
        CategoryFactory::createMany(5);
142
143
        $objects = repository(Category::class)->randomSet(3);
144
145
        $this->assertCount(3, $objects);
146
        $this->assertCount(3, \array_unique(\array_map(static function($category) { return $category->getId(); }, $objects)));
147
    }
148
149
    /**
150
     * @test
151
     */
152
    public function random_set_number_must_be_positive(): void
153
    {
154
        $this->expectException(\InvalidArgumentException::class);
155
        $this->expectExceptionMessage('$number must be positive (-1 given).');
156
157
        repository(Category::class)->randomSet(-1);
158
    }
159
160
    /**
161
     * @test
162
     */
163
    public function the_number_of_persisted_objects_must_be_at_least_the_random_set_number(): void
164
    {
165
        CategoryFactory::createOne();
166
167
        $this->expectException(\RuntimeException::class);
168
        $this->expectExceptionMessage(\sprintf('At least 2 "%s" object(s) must have been persisted (1 persisted).', Category::class));
169
170
        repository(Category::class)->randomSet(2);
171
    }
172
173
    /**
174
     * @test
175
     */
176
    public function can_find_random_range_of_objects(): void
177
    {
178
        CategoryFactory::createMany(5);
179
180
        $counts = [];
181
182
        while (4 !== \count(\array_unique($counts))) {
183
            $counts[] = \count(repository(Category::class)->randomRange(0, 3));
184
        }
185
186
        $this->assertCount(4, \array_unique($counts));
187
        $this->assertContains(0, $counts);
188
        $this->assertContains(1, $counts);
189
        $this->assertContains(2, $counts);
190
        $this->assertContains(3, $counts);
191
        $this->assertNotContains(4, $counts);
192
        $this->assertNotContains(5, $counts);
193
    }
194
195
    /**
196
     * @test
197
     */
198
    public function the_number_of_persisted_objects_must_be_at_least_the_random_range_max(): void
199
    {
200
        CategoryFactory::createOne();
201
202
        $this->expectException(\RuntimeException::class);
203
        $this->expectExceptionMessage(\sprintf('At least 2 "%s" object(s) must have been persisted (1 persisted).', Category::class));
204
205
        repository(Category::class)->randomRange(0, 2);
206
    }
207
208
    /**
209
     * @test
210
     */
211
    public function random_range_min_cannot_be_less_than_zero(): void
212
    {
213
        $this->expectException(\InvalidArgumentException::class);
214
        $this->expectExceptionMessage('$min must be positive (-1 given).');
215
216
        repository(Category::class)->randomRange(-1, 3);
217
    }
218
219
    /**
220
     * @test
221
     */
222
    public function random_set_max_cannot_be_less_than_min(): void
223
    {
224
        $this->expectException(\InvalidArgumentException::class);
225
        $this->expectExceptionMessage('$max (3) cannot be less than $min (5).');
226
227
        repository(Category::class)->randomRange(5, 3);
228
    }
229
230
    /**
231
     * @see https://github.com/zenstruck/foundry/issues/42
232
     *
233
     * @test
234
     */
235
    public function doctrine_proxies_are_converted_to_foundry_proxies(): void
236
    {
237
        PostFactory::createOne(['category' => CategoryFactory::new()]);
238
239
        // clear the em so nothing is tracked
240
        static::$kernel->getContainer()->get('doctrine')->getManager()->clear();
241
242
        // load a random Post which causes the em to track a "doctrine proxy" for category
243
        PostFactory::random();
244
245
        // load a random Category which should be a "doctrine proxy"
246
        $category = CategoryFactory::random()->object();
247
248
        // ensure the category is a "doctrine proxy" and a Category
249
        $this->assertInstanceOf(DoctrineProxy::class, $category);
250
        $this->assertInstanceOf(Category::class, $category);
251
    }
252
253
    /**
254
     * @test
255
     */
256
    public function proxy_wrapping_orm_entity_manager_can_order_by_in_find_one_by(): void
257
    {
258
        $categoryA = CategoryFactory::createOne();
259
        $categoryB = CategoryFactory::createOne();
260
        $categoryC = CategoryFactory::createOne();
261
262
        $this->assertSame($categoryC->getId(), CategoryFactory::repository()->findOneBy([], ['id' => 'DESC'])->getId());
263
    }
264
265
    /**
266
     * @test
267
     */
268
    public function first_and_last_return_the_correct_object(): void
269
    {
270
        $categoryA = CategoryFactory::createOne(['name' => '3']);
271
        $categoryB = CategoryFactory::createOne(['name' => '2']);
272
        $categoryC = CategoryFactory::createOne(['name' => '1']);
273
        $repository = CategoryFactory::repository();
274
275
        $this->assertSame($categoryA->getId(), $repository->first()->getId());
276
        $this->assertSame($categoryC->getId(), $repository->first('name')->getId());
277
        $this->assertSame($categoryC->getId(), $repository->last()->getId());
278
        $this->assertSame($categoryA->getId(), $repository->last('name')->getId());
279
    }
280
281
    /**
282
     * @test
283
     */
284
    public function first_and_last_return_null_if_empty(): void
285
    {
286
        $this->assertNull(CategoryFactory::repository()->first());
287
        $this->assertNull(CategoryFactory::repository()->first('name'));
288
        $this->assertNull(CategoryFactory::repository()->last());
289
        $this->assertNull(CategoryFactory::repository()->last('name'));
290
    }
291
292
    /**
293
     * @test
294
     */
295
    public function repository_proxy_is_countable_and_iterable(): void
296
    {
297
        CategoryFactory::createMany(4);
298
299
        $repository = CategoryFactory::repository();
300
301
        $this->assertCount(4, $repository);
302
        $this->assertCount(4, \iterator_to_array($repository));
303
    }
304
305
    /**
306
     * @test
307
     * @group legacy
308
     */
309
    public function can_use_get_count(): void
310
    {
311
        CategoryFactory::createMany(4);
312
313
        $this->expectDeprecation('Since zenstruck\foundry 1.5.0: Using RepositoryProxy::getCount() is deprecated, use RepositoryProxy::count() (it is now Countable).');
314
315
        $this->assertSame(4, CategoryFactory::repository()->getCount());
316
    }
317
}
318