zenstruck /
foundry
| 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
Bug
introduced
by
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 |