Passed
Pull Request — master (#81)
by Kevin
17:06
created

RepositoryProxyTest::can_find_random_object()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 5
nc 2
nop 0
dl 0
loc 11
rs 10
c 1
b 0
f 1
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 ResetDatabase, Factories, ExpectDeprecationTrait;
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());
0 ignored issues
show
Bug introduced by
The method customMethod() does not exist on Zenstruck\Foundry\RepositoryProxy. 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

29
        $this->assertSame('from custom method', repository(Post::class)->/** @scrutinizer ignore-call */ customMethod());
Loading history...
30
    }
31
32
    /**
33
     * @test
34
     */
35
    public function assertions(): void
36
    {
37
        $repository = repository(Category::class);
38
39
        $repository->assertEmpty();
40
41
        CategoryFactory::new()->createMany(2);
42
43
        $repository->assertCount(2);
44
        $repository->assertCountGreaterThan(1);
45
        $repository->assertCountGreaterThanOrEqual(2);
46
        $repository->assertCountLessThan(3);
47
        $repository->assertCountLessThanOrEqual(2);
48
    }
49
50
    /**
51
     * @test
52
     */
53
    public function can_fetch_objects(): void
54
    {
55
        $repository = repository(Category::class);
56
57
        CategoryFactory::new()->createMany(2);
58
59
        $objects = $repository->findAll();
60
61
        $this->assertCount(2, $objects);
62
        $this->assertInstanceOf(Proxy::class, $objects[0]);
63
64
        $objects = $repository->findBy([]);
65
66
        $this->assertCount(2, $objects);
67
        $this->assertInstanceOf(Proxy::class, $objects[0]);
68
    }
69
70
    /**
71
     * @test
72
     */
73
    public function find_can_be_passed_proxy_or_object_or_array(): void
74
    {
75
        $repository = repository(Category::class);
76
        $proxy = CategoryFactory::new()->create(['name' => 'foo']);
77
78
        $this->assertInstanceOf(Proxy::class, $repository->find($proxy));
79
        $this->assertInstanceOf(Proxy::class, $repository->find($proxy->object()));
80
        $this->assertInstanceOf(Proxy::class, $repository->find(['name' => 'foo']));
81
    }
82
83
    /**
84
     * @test
85
     */
86
    public function can_find_random_object(): void
87
    {
88
        CategoryFactory::new()->createMany(5);
89
90
        $ids = [];
91
92
        while (5 !== \count(\array_unique($ids))) {
93
            $ids[] = repository(Category::class)->random()->getId();
0 ignored issues
show
Bug introduced by
The method getId() 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

93
            $ids[] = repository(Category::class)->random()->/** @scrutinizer ignore-call */ getId();
Loading history...
94
        }
95
96
        $this->assertCount(5, \array_unique($ids));
97
    }
98
99
    /**
100
     * @test
101
     */
102
    public function at_least_one_object_must_exist_to_get_random_object(): void
103
    {
104
        $this->expectException(\RuntimeException::class);
105
        $this->expectExceptionMessage(\sprintf('At least 1 "%s" object(s) must have been persisted (0 persisted).', Category::class));
106
107
        repository(Category::class)->random();
108
    }
109
110
    /**
111
     * @test
112
     */
113
    public function can_find_random_set_of_objects(): void
114
    {
115
        CategoryFactory::new()->createMany(5);
116
117
        $objects = repository(Category::class)->randomSet(3);
118
119
        $this->assertCount(3, $objects);
120
        $this->assertCount(3, \array_unique(\array_map(static function($category) { return $category->getId(); }, $objects)));
121
    }
122
123
    /**
124
     * @test
125
     */
126
    public function random_set_number_must_be_positive(): void
127
    {
128
        $this->expectException(\InvalidArgumentException::class);
129
        $this->expectExceptionMessage('$number must be positive (-1 given).');
130
131
        repository(Category::class)->randomSet(-1);
132
    }
133
134
    /**
135
     * @test
136
     */
137
    public function the_number_of_persisted_objects_must_be_at_least_the_random_set_number(): void
138
    {
139
        CategoryFactory::new()->createMany(1);
140
141
        $this->expectException(\RuntimeException::class);
142
        $this->expectExceptionMessage(\sprintf('At least 2 "%s" object(s) must have been persisted (1 persisted).', Category::class));
143
144
        repository(Category::class)->randomSet(2);
145
    }
146
147
    /**
148
     * @test
149
     */
150
    public function can_find_random_range_of_objects(): void
151
    {
152
        CategoryFactory::new()->createMany(5);
153
154
        $counts = [];
155
156
        while (4 !== \count(\array_unique($counts))) {
157
            $counts[] = \count(repository(Category::class)->randomRange(0, 3));
158
        }
159
160
        $this->assertCount(4, \array_unique($counts));
161
        $this->assertContains(0, $counts);
162
        $this->assertContains(1, $counts);
163
        $this->assertContains(2, $counts);
164
        $this->assertContains(3, $counts);
165
        $this->assertNotContains(4, $counts);
166
        $this->assertNotContains(5, $counts);
167
    }
168
169
    /**
170
     * @test
171
     */
172
    public function the_number_of_persisted_objects_must_be_at_least_the_random_range_max(): void
173
    {
174
        CategoryFactory::new()->createMany(1);
175
176
        $this->expectException(\RuntimeException::class);
177
        $this->expectExceptionMessage(\sprintf('At least 2 "%s" object(s) must have been persisted (1 persisted).', Category::class));
178
179
        repository(Category::class)->randomRange(0, 2);
180
    }
181
182
    /**
183
     * @test
184
     */
185
    public function random_range_min_cannot_be_less_than_zero(): void
186
    {
187
        $this->expectException(\InvalidArgumentException::class);
188
        $this->expectExceptionMessage('$min must be positive (-1 given).');
189
190
        repository(Category::class)->randomRange(-1, 3);
191
    }
192
193
    /**
194
     * @test
195
     */
196
    public function random_set_max_cannot_be_less_than_min(): void
197
    {
198
        $this->expectException(\InvalidArgumentException::class);
199
        $this->expectExceptionMessage('$max (3) cannot be less than $min (5).');
200
201
        repository(Category::class)->randomRange(5, 3);
202
    }
203
204
    /**
205
     * @see https://github.com/zenstruck/foundry/issues/42
206
     *
207
     * @test
208
     */
209
    public function doctrine_proxies_are_converted_to_foundry_proxies(): void
210
    {
211
        PostFactory::new()->create(['category' => CategoryFactory::new()]);
212
213
        // clear the em so nothing is tracked
214
        static::$kernel->getContainer()->get('doctrine')->getManager()->clear();
215
216
        // load a random Post which causes the em to track a "doctrine proxy" for category
217
        PostFactory::random();
218
219
        // load a random Category which should be a "doctrine proxy"
220
        $category = CategoryFactory::random()->object();
221
222
        // ensure the category is a "doctrine proxy" and a Category
223
        $this->assertInstanceOf(DoctrineProxy::class, $category);
224
        $this->assertInstanceOf(Category::class, $category);
225
    }
226
227
    /**
228
     * @test
229
     */
230
    public function proxy_wrapping_orm_entity_manager_can_order_by_in_find_one_by(): void
231
    {
232
        $categoryA = CategoryFactory::new()->create();
0 ignored issues
show
Unused Code introduced by
The assignment to $categoryA is dead and can be removed.
Loading history...
233
        $categoryB = CategoryFactory::new()->create();
0 ignored issues
show
Unused Code introduced by
The assignment to $categoryB is dead and can be removed.
Loading history...
234
        $categoryC = CategoryFactory::new()->create();
235
236
        $this->assertSame($categoryC->getId(), CategoryFactory::repository()->findOneBy([], ['id' => 'DESC'])->getId());
237
    }
238
239
    /**
240
     * @test
241
     */
242
    public function first_and_last_return_the_correct_object(): void
243
    {
244
        $categoryA = CategoryFactory::new()->create(['name' => '3']);
245
        $categoryB = CategoryFactory::new()->create(['name' => '2']);
0 ignored issues
show
Unused Code introduced by
The assignment to $categoryB is dead and can be removed.
Loading history...
246
        $categoryC = CategoryFactory::new()->create(['name' => '1']);
247
        $repository = CategoryFactory::repository();
248
249
        $this->assertSame($categoryA->getId(), $repository->first()->getId());
250
        $this->assertSame($categoryC->getId(), $repository->first('name')->getId());
251
        $this->assertSame($categoryC->getId(), $repository->last()->getId());
252
        $this->assertSame($categoryA->getId(), $repository->last('name')->getId());
253
    }
254
255
    /**
256
     * @test
257
     */
258
    public function first_and_last_return_null_if_empty(): void
259
    {
260
        $this->assertNull(CategoryFactory::repository()->first());
261
        $this->assertNull(CategoryFactory::repository()->first('name'));
262
        $this->assertNull(CategoryFactory::repository()->last());
263
        $this->assertNull(CategoryFactory::repository()->last('name'));
264
    }
265
266
    /**
267
     * @test
268
     */
269
    public function repository_proxy_is_countable_and_iterable(): void
270
    {
271
        CategoryFactory::new()->createMany(4);
272
273
        $repository = CategoryFactory::repository();
274
275
        $this->assertCount(4, $repository);
276
        $this->assertCount(4, \iterator_to_array($repository));
277
    }
278
279
    /**
280
     * @test
281
     * @group legacy
282
     */
283
    public function can_use_get_count(): void
284
    {
285
        CategoryFactory::new()->createMany(4);
286
287
        $this->expectDeprecation('Since zenstruck\foundry 1.5.0: Using RepositoryProxy::getCount() is deprecated, use RepositoryProxy::count() (it is now Countable).');
288
289
        $this->assertSame(4, CategoryFactory::repository()->getCount());
0 ignored issues
show
Deprecated Code introduced by
The function Zenstruck\Foundry\RepositoryProxy::getCount() has been deprecated: use RepositoryProxy::count() ( Ignorable by Annotation )

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

289
        $this->assertSame(4, /** @scrutinizer ignore-deprecated */ CategoryFactory::repository()->getCount());

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
290
    }
291
}
292