EmbeddedRelationsTest.php 32.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
<?php

class EmbeddedRelationsTest extends TestCase {

    public function tearDown()
    {
        Mockery::close();

        User::truncate();
        Book::truncate();
        Item::truncate();
        Role::truncate();
        Client::truncate();
        Group::truncate();
        Photo::truncate();
    }

    public function testEmbedsManySave()
    {
20 21
        $user = User::create(['name' => 'John Doe']);
        $address = new Address(['city' => 'London']);
22 23

        $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
24 25 26 27
        $events->shouldReceive('until')->once()->with('eloquent.saving: ' . get_class($address), $address)->andReturn(true);
        $events->shouldReceive('until')->once()->with('eloquent.creating: ' . get_class($address), $address)->andReturn(true);
        $events->shouldReceive('fire')->once()->with('eloquent.created: ' . get_class($address), $address);
        $events->shouldReceive('fire')->once()->with('eloquent.saved: ' . get_class($address), $address);
28 29 30 31

        $address = $user->addresses()->save($address);
        $address->unsetEventDispatcher();

32 33
        $this->assertNotNull($user->addresses);
        $this->assertInstanceOf('Illuminate\Database\Eloquent\Collection', $user->addresses);
34
        $this->assertEquals(['London'], $user->addresses->lists('city')->all());
35 36 37 38 39 40 41 42
        $this->assertInstanceOf('DateTime', $address->created_at);
        $this->assertInstanceOf('DateTime', $address->updated_at);
        $this->assertNotNull($address->_id);
        $this->assertTrue(is_string($address->_id));

        $raw = $address->getAttributes();
        $this->assertInstanceOf('MongoId', $raw['_id']);

43
        $address = $user->addresses()->save(new Address(['city' => 'Paris']));
44 45

        $user = User::find($user->_id);
46
        $this->assertEquals(['London', 'Paris'], $user->addresses->lists('city')->all());
47 48

        $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
49 50 51 52
        $events->shouldReceive('until')->once()->with('eloquent.saving: ' . get_class($address), $address)->andReturn(true);
        $events->shouldReceive('until')->once()->with('eloquent.updating: ' . get_class($address), $address)->andReturn(true);
        $events->shouldReceive('fire')->once()->with('eloquent.updated: ' . get_class($address), $address);
        $events->shouldReceive('fire')->once()->with('eloquent.saved: ' . get_class($address), $address);
53 54 55 56 57 58 59 60 61

        $address->city = 'New York';
        $user->addresses()->save($address);
        $address->unsetEventDispatcher();

        $this->assertEquals(2, count($user->addresses));
        $this->assertEquals(2, count($user->addresses()->get()));
        $this->assertEquals(2, $user->addresses->count());
        $this->assertEquals(2, $user->addresses()->count());
62
        $this->assertEquals(['London', 'New York'], $user->addresses->lists('city')->all());
63 64

        $freshUser = User::find($user->_id);
65
        $this->assertEquals(['London', 'New York'], $freshUser->addresses->lists('city')->all());
66 67 68 69 70 71 72 73 74

        $address = $user->addresses->first();
        $this->assertEquals('London', $address->city);
        $this->assertInstanceOf('DateTime', $address->created_at);
        $this->assertInstanceOf('DateTime', $address->updated_at);
        $this->assertInstanceOf('User', $address->user);
        $this->assertEmpty($address->relationsToArray()); // prevent infinite loop

        $user = User::find($user->_id);
75
        $user->addresses()->save(new Address(['city' => 'Bruxelles']));
76
        $this->assertEquals(['London', 'New York', 'Bruxelles'], $user->addresses->lists('city')->all());
77

78 79 80
        $address = $user->addresses[1];
        $address->city = "Manhattan";
        $user->addresses()->save($address);
81
        $this->assertEquals(['London', 'Manhattan', 'Bruxelles'], $user->addresses->lists('city')->all());
82 83

        $freshUser = User::find($user->_id);
84
        $this->assertEquals(['London', 'Manhattan', 'Bruxelles'], $freshUser->addresses->lists('city')->all());
85 86
    }

87 88 89 90
    // public function testEmbedsManySaveModel()
    // {
    //     $user = User::create(['name' => 'John Doe']);
    //     $address = new Address(['city' => 'London']);
91

92 93 94 95 96
    //     $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
    //     $events->shouldReceive('until')->once()->with('eloquent.saving: ' . get_class($address), $address)->andReturn(true);
    //     $events->shouldReceive('until')->once()->with('eloquent.creating: ' . get_class($address), $address)->andReturn(true);
    //     $events->shouldReceive('fire')->once()->with('eloquent.created: ' . get_class($address), $address);
    //     $events->shouldReceive('fire')->once()->with('eloquent.saved: ' . get_class($address), $address);
97

98
    //     $address->save();
99

100 101 102 103 104
    //     $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
    //     $events->shouldReceive('until')->once()->with('eloquent.saving: ' . get_class($address), $address)->andReturn(true);
    //     $events->shouldReceive('until')->once()->with('eloquent.updating: ' . get_class($address), $address)->andReturn(true);
    //     $events->shouldReceive('fire')->once()->with('eloquent.updated: ' . get_class($address), $address);
    //     $events->shouldReceive('fire')->once()->with('eloquent.saved: ' . get_class($address), $address);
105

106 107 108
    //     $address->city = 'Paris';
    //     $address->save();
    // }
109

110 111
    public function testEmbedsToArray()
    {
112 113
        $user = User::create(['name' => 'John Doe']);
        $user->addresses()->saveMany([new Address(['city' => 'London']), new Address(['city' => 'Bristol'])]);
114 115 116 117 118 119

        $array = $user->toArray();
        $this->assertFalse(array_key_exists('_addresses', $array));
        $this->assertTrue(array_key_exists('addresses', $array));
    }

120 121
    public function testEmbedsManyAssociate()
    {
122 123
        $user = User::create(['name' => 'John Doe']);
        $address = new Address(['city' => 'London']);
124

125
        $user->addresses()->associate($address);
126
        $this->assertEquals(['London'], $user->addresses->lists('city')->all());
127 128 129
        $this->assertNotNull($address->_id);

        $freshUser = User::find($user->_id);
130
        $this->assertEquals([], $freshUser->addresses->lists('city')->all());
131 132 133

        $address->city = 'Londinium';
        $user->addresses()->associate($address);
134
        $this->assertEquals(['Londinium'], $user->addresses->lists('city')->all());
135 136

        $freshUser = User::find($user->_id);
137
        $this->assertEquals([], $freshUser->addresses->lists('city')->all());
138 139 140 141
    }

    public function testEmbedsManySaveMany()
    {
142 143
        $user = User::create(['name' => 'John Doe']);
        $user->addresses()->saveMany([new Address(['city' => 'London']), new Address(['city' => 'Bristol'])]);
144
        $this->assertEquals(['London', 'Bristol'], $user->addresses->lists('city')->all());
145 146

        $freshUser = User::find($user->id);
147
        $this->assertEquals(['London', 'Bristol'], $freshUser->addresses->lists('city')->all());
148 149 150 151
    }

    public function testEmbedsManyDuplicate()
    {
152 153
        $user = User::create(['name' => 'John Doe']);
        $address = new Address(['city' => 'London']);
154 155 156
        $user->addresses()->save($address);
        $user->addresses()->save($address);
        $this->assertEquals(1, $user->addresses->count());
157
        $this->assertEquals(['London'], $user->addresses->lists('city')->all());
158 159 160 161 162 163 164

        $user = User::find($user->id);
        $this->assertEquals(1, $user->addresses->count());

        $address->city = 'Paris';
        $user->addresses()->save($address);
        $this->assertEquals(1, $user->addresses->count());
165
        $this->assertEquals(['Paris'], $user->addresses->lists('city')->all());
166

167
        $user->addresses()->create(['_id' => $address->_id, 'city' => 'Bruxelles']);
168
        $this->assertEquals(1, $user->addresses->count());
169
        $this->assertEquals(['Bruxelles'], $user->addresses->lists('city')->all());
170 171 172 173
    }

    public function testEmbedsManyCreate()
    {
174 175
        $user = User::create([]);
        $address = $user->addresses()->create(['city' => 'Bruxelles']);
176 177
        $this->assertInstanceOf('Address', $address);
        $this->assertTrue(is_string($address->_id));
178
        $this->assertEquals(['Bruxelles'], $user->addresses->lists('city')->all());
179 180 181 182 183

        $raw = $address->getAttributes();
        $this->assertInstanceOf('MongoId', $raw['_id']);

        $freshUser = User::find($user->id);
184
        $this->assertEquals(['Bruxelles'], $freshUser->addresses->lists('city')->all());
185

186 187
        $user = User::create([]);
        $address = $user->addresses()->create(['_id' => '', 'city' => 'Bruxelles']);
188 189 190 191 192 193 194 195
        $this->assertTrue(is_string($address->_id));

        $raw = $address->getAttributes();
        $this->assertInstanceOf('MongoId', $raw['_id']);
    }

    public function testEmbedsManyCreateMany()
    {
196 197
        $user = User::create([]);
        list($bruxelles, $paris) = $user->addresses()->createMany([['city' => 'Bruxelles'], ['city' => 'Paris']]);
198 199
        $this->assertInstanceOf('Address', $bruxelles);
        $this->assertEquals('Bruxelles', $bruxelles->city);
200
        $this->assertEquals(['Bruxelles', 'Paris'], $user->addresses->lists('city')->all());
201 202

        $freshUser = User::find($user->id);
203
        $this->assertEquals(['Bruxelles', 'Paris'], $freshUser->addresses->lists('city')->all());
204 205
    }

Jens Segers's avatar
Jens Segers committed
206
    public function testEmbedsManyDestroy()
207
    {
208 209
        $user = User::create(['name' => 'John Doe']);
        $user->addresses()->saveMany([new Address(['city' => 'London']), new Address(['city' => 'Bristol']), new Address(['city' => 'Bruxelles'])]);
210 211 212 213

        $address = $user->addresses->first();

        $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
214 215
        $events->shouldReceive('until')->once()->with('eloquent.deleting: ' . get_class($address), Mockery::type('Address'))->andReturn(true);
        $events->shouldReceive('fire')->once()->with('eloquent.deleted: ' . get_class($address), Mockery::type('Address'));
216 217

        $user->addresses()->destroy($address->_id);
218
        $this->assertEquals(['Bristol', 'Bruxelles'], $user->addresses->lists('city')->all());
219 220 221 222 223

        $address->unsetEventDispatcher();

        $address = $user->addresses->first();
        $user->addresses()->destroy($address);
224
        $this->assertEquals(['Bruxelles'], $user->addresses->lists('city')->all());
225

226 227
        $user->addresses()->create(['city' => 'Paris']);
        $user->addresses()->create(['city' => 'San Francisco']);
228 229

        $freshUser = User::find($user->id);
230
        $this->assertEquals(['Bruxelles', 'Paris', 'San Francisco'], $freshUser->addresses->lists('city')->all());
231 232 233

        $ids = $user->addresses->lists('_id');
        $user->addresses()->destroy($ids);
234
        $this->assertEquals([], $user->addresses->lists('city')->all());
235 236

        $freshUser = User::find($user->id);
237
        $this->assertEquals([], $freshUser->addresses->lists('city')->all());
238

239 240
        list($london, $bristol, $bruxelles) = $user->addresses()->saveMany([new Address(['city' => 'London']), new Address(['city' => 'Bristol']), new Address(['city' => 'Bruxelles'])]);
        $user->addresses()->destroy([$london, $bruxelles]);
241
        $this->assertEquals(['Bristol'], $user->addresses->lists('city')->all());
Jens Segers's avatar
Jens Segers committed
242
    }
243

244 245
    public function testEmbedsManyDelete()
    {
246 247
        $user = User::create(['name' => 'John Doe']);
        $user->addresses()->saveMany([new Address(['city' => 'London']), new Address(['city' => 'Bristol']), new Address(['city' => 'Bruxelles'])]);
248 249 250 251

        $address = $user->addresses->first();

        $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
252 253
        $events->shouldReceive('until')->once()->with('eloquent.deleting: ' . get_class($address), Mockery::type('Address'))->andReturn(true);
        $events->shouldReceive('fire')->once()->with('eloquent.deleted: ' . get_class($address), Mockery::type('Address'));
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269

        $address->delete();

        $this->assertEquals(2, $user->addresses()->count());
        $this->assertEquals(2, $user->addresses->count());

        $address->unsetEventDispatcher();

        $address = $user->addresses->first();
        $address->delete();

        $user = User::where('name', 'John Doe')->first();
        $this->assertEquals(1, $user->addresses()->count());
        $this->assertEquals(1, $user->addresses->count());
    }

270 271
    public function testEmbedsManyDissociate()
    {
272 273
        $user = User::create([]);
        $cordoba = $user->addresses()->create(['city' => 'Cordoba']);
274 275 276 277 278 279 280 281 282 283

        $user->addresses()->dissociate($cordoba->id);

        $freshUser = User::find($user->id);
        $this->assertEquals(0, $user->addresses->count());
        $this->assertEquals(1, $freshUser->addresses->count());
    }

    public function testEmbedsManyAliases()
    {
284 285
        $user = User::create(['name' => 'John Doe']);
        $address = new Address(['city' => 'London']);
286 287

        $address = $user->addresses()->attach($address);
288
        $this->assertEquals(['London'], $user->addresses->lists('city')->all());
289 290

        $user->addresses()->detach($address);
291
        $this->assertEquals([], $user->addresses->lists('city')->all());
292 293 294 295
    }

    public function testEmbedsManyCreatingEventReturnsFalse()
    {
296 297
        $user = User::create(['name' => 'John Doe']);
        $address = new Address(['city' => 'London']);
298 299

        $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
300 301
        $events->shouldReceive('until')->once()->with('eloquent.saving: ' . get_class($address), $address)->andReturn(true);
        $events->shouldReceive('until')->once()->with('eloquent.creating: ' . get_class($address), $address)->andReturn(false);
302 303 304 305 306 307 308

        $this->assertFalse($user->addresses()->save($address));
        $address->unsetEventDispatcher();
    }

    public function testEmbedsManySavingEventReturnsFalse()
    {
309 310
        $user = User::create(['name' => 'John Doe']);
        $address = new Address(['city' => 'Paris']);
311 312 313
        $address->exists = true;

        $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
314
        $events->shouldReceive('until')->once()->with('eloquent.saving: ' . get_class($address), $address)->andReturn(false);
315 316 317 318 319 320 321

        $this->assertFalse($user->addresses()->save($address));
        $address->unsetEventDispatcher();
    }

    public function testEmbedsManyUpdatingEventReturnsFalse()
    {
322 323
        $user = User::create(['name' => 'John Doe']);
        $address = new Address(['city' => 'New York']);
324 325 326
        $user->addresses()->save($address);

        $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
327 328
        $events->shouldReceive('until')->once()->with('eloquent.saving: ' . get_class($address), $address)->andReturn(true);
        $events->shouldReceive('until')->once()->with('eloquent.updating: ' . get_class($address), $address)->andReturn(false);
329 330 331 332 333 334 335 336 337

        $address->city = 'Warsaw';

        $this->assertFalse($user->addresses()->save($address));
        $address->unsetEventDispatcher();
    }

    public function testEmbedsManyDeletingEventReturnsFalse()
    {
338 339
        $user = User::create(['name' => 'John Doe']);
        $user->addresses()->save(new Address(['city' => 'New York']));
340 341 342 343

        $address = $user->addresses->first();

        $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
344
        $events->shouldReceive('until')->once()->with('eloquent.deleting: ' . get_class($address), Mockery::mustBe($address))->andReturn(false);
345 346

        $this->assertEquals(0, $user->addresses()->destroy($address));
347
        $this->assertEquals(['New York'], $user->addresses->lists('city')->all());
348 349 350 351 352 353

        $address->unsetEventDispatcher();
    }

    public function testEmbedsManyFindOrContains()
    {
354 355 356
        $user = User::create(['name' => 'John Doe']);
        $address1 = $user->addresses()->save(new Address(['city' => 'New York']));
        $address2 = $user->addresses()->save(new Address(['city' => 'Paris']));
357 358 359 360 361 362 363 364 365 366 367 368 369

        $address = $user->addresses()->find($address1->_id);
        $this->assertEquals($address->city, $address1->city);

        $address = $user->addresses()->find($address2->_id);
        $this->assertEquals($address->city, $address2->city);

        $this->assertTrue($user->addresses()->contains($address2->_id));
        $this->assertFalse($user->addresses()->contains('123'));
    }

    public function testEmbedsManyEagerLoading()
    {
370 371 372
        $user1 = User::create(['name' => 'John Doe']);
        $user1->addresses()->save(new Address(['city' => 'New York']));
        $user1->addresses()->save(new Address(['city' => 'Paris']));
373

374 375 376
        $user2 = User::create(['name' => 'Jane Doe']);
        $user2->addresses()->save(new Address(['city' => 'Berlin']));
        $user2->addresses()->save(new Address(['city' => 'Paris']));
377 378 379 380

        $user = User::find($user1->id);
        $relations = $user->getRelations();
        $this->assertFalse(array_key_exists('addresses', $relations));
381 382
        $this->assertArrayHasKey('addresses', $user->toArray());
        $this->assertTrue(is_array($user->toArray()['addresses']));
383 384 385 386 387

        $user = User::with('addresses')->get()->first();
        $relations = $user->getRelations();
        $this->assertTrue(array_key_exists('addresses', $relations));
        $this->assertEquals(2, $relations['addresses']->count());
388
        $this->assertArrayHasKey('addresses', $user->toArray());
389
        $this->assertTrue(is_array($user->toArray()['addresses']));
390 391
    }

392
    public function testEmbedsManyDeleteAll()
393
    {
394 395 396
        $user1 = User::create(['name' => 'John Doe']);
        $user1->addresses()->save(new Address(['city' => 'New York']));
        $user1->addresses()->save(new Address(['city' => 'Paris']));
397

398 399 400
        $user2 = User::create(['name' => 'Jane Doe']);
        $user2->addresses()->save(new Address(['city' => 'Berlin']));
        $user2->addresses()->save(new Address(['city' => 'Paris']));
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417

        $user1->addresses()->delete();
        $this->assertEquals(0, $user1->addresses()->count());
        $this->assertEquals(0, $user1->addresses->count());
        $this->assertEquals(2, $user2->addresses()->count());
        $this->assertEquals(2, $user2->addresses->count());

        $user1 = User::find($user1->id);
        $user2 = User::find($user2->id);
        $this->assertEquals(0, $user1->addresses()->count());
        $this->assertEquals(0, $user1->addresses->count());
        $this->assertEquals(2, $user2->addresses()->count());
        $this->assertEquals(2, $user2->addresses->count());
    }

    public function testEmbedsManyCollectionMethods()
    {
418 419 420 421 422
        $user = User::create(['name' => 'John Doe']);
        $user->addresses()->save(new Address(['city' => 'Paris', 'country' => 'France', 'visited' => 4, 'created_at' => new DateTime('3 days ago')]));
        $user->addresses()->save(new Address(['city' => 'Bruges', 'country' => 'Belgium', 'visited' => 7, 'created_at' => new DateTime('5 days ago')]));
        $user->addresses()->save(new Address(['city' => 'Brussels', 'country' => 'Belgium', 'visited' => 2, 'created_at' => new DateTime('4 days ago')]));
        $user->addresses()->save(new Address(['city' => 'Ghent', 'country' => 'Belgium', 'visited' => 13, 'created_at' => new DateTime('2 days ago')]));
423

424 425 426 427
        $this->assertEquals(['Paris', 'Bruges', 'Brussels', 'Ghent'], $user->addresses()->lists('city')->all());
        $this->assertEquals(['Bruges', 'Brussels', 'Ghent', 'Paris'], $user->addresses()->sortBy('city')->lists('city')->all());
        $this->assertEquals(['Bruges', 'Brussels', 'Ghent', 'Paris'], $user->addresses()->orderBy('city')->lists('city')->all());
        $this->assertEquals(['Paris', 'Ghent', 'Brussels', 'Bruges'], $user->addresses()->orderBy('city', 'desc')->lists('city')->all());
428

429 430 431
        $this->assertEquals([], $user->addresses()->where('city', 'New York')->lists('city')->all());
        $this->assertEquals(['Bruges', 'Brussels', 'Ghent'], $user->addresses()->where('country', 'Belgium')->lists('city')->all());
        $this->assertEquals(['Ghent', 'Brussels', 'Bruges'], $user->addresses()->where('country', 'Belgium')->orderBy('city', 'desc')->lists('city')->all());
432

433 434 435
        $results = $user->addresses->get(0);
        $this->assertInstanceOf('Address', $results);

436 437 438
        $results = $user->addresses()->where('country', 'Belgium')->get();
        $this->assertInstanceOf('Jenssegers\Mongodb\Eloquent\Collection', $results);
        $this->assertEquals(3, $results->count());
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454

        $results = $user->addresses()->where('country', '!=', 'Belgium')->get();
        $this->assertEquals(1, $results->count());

        $results = $user->addresses()->where('visited', '>', 4)->get();
        $this->assertEquals(2, $results->count());

        $results = $user->addresses()->where('visited', '<', 7)->get();
        $this->assertEquals(2, $results->count());

        $results = $user->addresses()->where('visited', '<=', 7)->get();
        $this->assertEquals(3, $results->count());

        $results = $user->addresses()->where('visited', '>=', 7)->get();
        $this->assertEquals(2, $results->count());

455
        $results = $user->addresses()->where('visited', 'between', [4, 7])->get();
456
        $this->assertEquals(2, $results->count());
457

458
        $results = $user->addresses()->whereBetween('visited', [4, 7])->get();
459 460
        $this->assertEquals(2, $results->count());

461
        $results = $user->addresses()->whereNotBetween('visited', [4, 7])->get();
462 463
        $this->assertEquals(2, $results->count());

464
        $results = $user->addresses()->whereIn('visited', [7, 13])->get();
465 466
        $this->assertEquals(2, $results->count());

467
        $results = $user->addresses()->whereNotIn('visited', [7])->get();
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489
        $this->assertEquals(3, $results->count());

        $results = $user->addresses()->whereNull('something')->get();
        $this->assertEquals(4, $results->count());

        $results = $user->addresses()->whereNotNull('visited')->get();
        $this->assertEquals(4, $results->count());

        $results = $user->addresses()->offset(1)->get();
        $this->assertEquals(3, $results->count());

        $results = $user->addresses()->skip(1)->get();
        $this->assertEquals(3, $results->count());

        $results = $user->addresses()->limit(2)->get();
        $this->assertEquals(2, $results->count());

        $result = $user->addresses()->latest()->first();
        $this->assertEquals('Ghent', $result->city);

        $result = $user->addresses()->oldest()->first();
        $this->assertEquals('Bruges', $result->city);
490 491 492 493
    }

    public function testEmbedsOne()
    {
494 495
        $user = User::create(['name' => 'John Doe']);
        $father = new User(['name' => 'Mark Doe']);
496 497

        $father->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
498 499 500 501
        $events->shouldReceive('until')->once()->with('eloquent.saving: ' . get_class($father), $father)->andReturn(true);
        $events->shouldReceive('until')->once()->with('eloquent.creating: ' . get_class($father), $father)->andReturn(true);
        $events->shouldReceive('fire')->once()->with('eloquent.created: ' . get_class($father), $father);
        $events->shouldReceive('fire')->once()->with('eloquent.saved: ' . get_class($father), $father);
502 503 504 505

        $father = $user->father()->save($father);
        $father->unsetEventDispatcher();

506
        $this->assertNotNull($user->father);
507 508 509 510 511 512 513 514 515 516
        $this->assertEquals('Mark Doe', $user->father->name);
        $this->assertInstanceOf('DateTime', $father->created_at);
        $this->assertInstanceOf('DateTime', $father->updated_at);
        $this->assertNotNull($father->_id);
        $this->assertTrue(is_string($father->_id));

        $raw = $father->getAttributes();
        $this->assertInstanceOf('MongoId', $raw['_id']);

        $father->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
517 518 519 520
        $events->shouldReceive('until')->once()->with('eloquent.saving: ' . get_class($father), $father)->andReturn(true);
        $events->shouldReceive('until')->once()->with('eloquent.updating: ' . get_class($father), $father)->andReturn(true);
        $events->shouldReceive('fire')->once()->with('eloquent.updated: ' . get_class($father), $father);
        $events->shouldReceive('fire')->once()->with('eloquent.saved: ' . get_class($father), $father);
521 522 523 524 525

        $father->name = 'Tom Doe';
        $user->father()->save($father);
        $father->unsetEventDispatcher();

526
        $this->assertNotNull($user->father);
527 528
        $this->assertEquals('Tom Doe', $user->father->name);

529
        $father = new User(['name' => 'Jim Doe']);
530 531

        $father->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
532 533 534 535
        $events->shouldReceive('until')->once()->with('eloquent.saving: ' . get_class($father), $father)->andReturn(true);
        $events->shouldReceive('until')->once()->with('eloquent.creating: ' . get_class($father), $father)->andReturn(true);
        $events->shouldReceive('fire')->once()->with('eloquent.created: ' . get_class($father), $father);
        $events->shouldReceive('fire')->once()->with('eloquent.saved: ' . get_class($father), $father);
536 537 538 539

        $father = $user->father()->save($father);
        $father->unsetEventDispatcher();

540
        $this->assertNotNull($user->father);
541 542 543
        $this->assertEquals('Jim Doe', $user->father->name);
    }

544 545
    public function testEmbedsOneAssociate()
    {
546 547
        $user = User::create(['name' => 'John Doe']);
        $father = new User(['name' => 'Mark Doe']);
548 549

        $father->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
550
        $events->shouldReceive('until')->times(0)->with('eloquent.saving: ' . get_class($father), $father);
551 552 553 554

        $father = $user->father()->associate($father);
        $father->unsetEventDispatcher();

555
        $this->assertNotNull($user->father);
556 557 558
        $this->assertEquals('Mark Doe', $user->father->name);
    }

559 560
    public function testEmbedsOneDelete()
    {
561 562
        $user = User::create(['name' => 'John Doe']);
        $father = $user->father()->save(new User(['name' => 'Mark Doe']));
563 564 565 566 567

        $user->father()->delete();
        $this->assertNull($user->father);
    }

568 569
    public function testEmbedsManyToArray()
    {
570 571 572 573
        $user = User::create(['name' => 'John Doe']);
        $user->addresses()->save(new Address(['city' => 'New York']));
        $user->addresses()->save(new Address(['city' => 'Paris']));
        $user->addresses()->save(new Address(['city' => 'Brussels']));
574 575

        $array = $user->toArray();
576 577
        $this->assertArrayHasKey('addresses', $array);
        $this->assertTrue(is_array($array['addresses']));
578 579
    }

580 581
    public function testEmbeddedSave()
    {
582 583 584
        $user = User::create(['name' => 'John Doe']);
        $address = $user->addresses()->create(['city' => 'New York']);
        $father = $user->father()->create(['name' => 'Mark Doe']);
585 586 587 588 589 590 591 592 593 594 595 596 597

        $address->city = 'Paris';
        $address->save();

        $father->name = 'Steve Doe';
        $father->save();

        $this->assertEquals('Paris', $user->addresses->first()->city);
        $this->assertEquals('Steve Doe', $user->father->name);

        $user = User::where('name', 'John Doe')->first();
        $this->assertEquals('Paris', $user->addresses->first()->city);
        $this->assertEquals('Steve Doe', $user->father->name);
Jens Segers's avatar
Jens Segers committed
598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613

        $address = $user->addresses()->first();
        $father = $user->father;

        $address->city = 'Ghent';
        $address->save();

        $father->name = 'Mark Doe';
        $father->save();

        $this->assertEquals('Ghent', $user->addresses->first()->city);
        $this->assertEquals('Mark Doe', $user->father->name);

        $user = User::where('name', 'John Doe')->first();
        $this->assertEquals('Ghent', $user->addresses->first()->city);
        $this->assertEquals('Mark Doe', $user->father->name);
614 615
    }

616 617
    public function testNestedEmbedsOne()
    {
618 619 620 621
        $user = User::create(['name' => 'John Doe']);
        $father = $user->father()->create(['name' => 'Mark Doe']);
        $grandfather = $father->father()->create(['name' => 'Steve Doe']);
        $greatgrandfather = $grandfather->father()->create(['name' => 'Tom Doe']);
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645

        $user->name = 'Tim Doe';
        $user->save();

        $father->name = 'Sven Doe';
        $father->save();

        $greatgrandfather->name = 'Ron Doe';
        $greatgrandfather->save();

        $this->assertEquals('Tim Doe', $user->name);
        $this->assertEquals('Sven Doe', $user->father->name);
        $this->assertEquals('Steve Doe', $user->father->father->name);
        $this->assertEquals('Ron Doe', $user->father->father->father->name);

        $user = User::where('name', 'Tim Doe')->first();
        $this->assertEquals('Tim Doe', $user->name);
        $this->assertEquals('Sven Doe', $user->father->name);
        $this->assertEquals('Steve Doe', $user->father->father->name);
        $this->assertEquals('Ron Doe', $user->father->father->father->name);
    }

    public function testNestedEmbedsMany()
    {
646 647 648 649 650 651
        $user = User::create(['name' => 'John Doe']);
        $country1 = $user->addresses()->create(['country' => 'France']);
        $country2 = $user->addresses()->create(['country' => 'Belgium']);
        $city1 = $country1->addresses()->create(['city' => 'Paris']);
        $city2 = $country2->addresses()->create(['city' => 'Ghent']);
        $city3 = $country2->addresses()->create(['city' => 'Brussels']);
652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667

        $city3->city = 'Bruges';
        $city3->save();

        $this->assertEquals(2, $user->addresses()->count());
        $this->assertEquals(1, $user->addresses()->first()->addresses()->count());
        $this->assertEquals(2, $user->addresses()->last()->addresses()->count());

        $user = User::where('name', 'John Doe')->first();
        $this->assertEquals(2, $user->addresses()->count());
        $this->assertEquals(1, $user->addresses()->first()->addresses()->count());
        $this->assertEquals(2, $user->addresses()->last()->addresses()->count());
    }

    public function testNestedMixedEmbeds()
    {
668 669 670 671
        $user = User::create(['name' => 'John Doe']);
        $father = $user->father()->create(['name' => 'Mark Doe']);
        $country1 = $father->addresses()->create(['country' => 'France']);
        $country2 = $father->addresses()->create(['country' => 'Belgium']);
672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688

        $country2->country = 'England';
        $country2->save();

        $father->name = 'Steve Doe';
        $father->save();

        $this->assertEquals('France', $user->father->addresses()->first()->country);
        $this->assertEquals('England', $user->father->addresses()->last()->country);
        $this->assertEquals('Steve Doe', $user->father->name);

        $user = User::where('name', 'John Doe')->first();
        $this->assertEquals('France', $user->father->addresses()->first()->country);
        $this->assertEquals('England', $user->father->addresses()->last()->country);
        $this->assertEquals('Steve Doe', $user->father->name);
    }

Jens Segers's avatar
Jens Segers committed
689 690
    public function testDoubleAssociate()
    {
691 692
        $user = User::create(['name' => 'John Doe']);
        $address = new Address(['city' => 'Paris']);
Jens Segers's avatar
Jens Segers committed
693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708

        $user->addresses()->associate($address);
        $user->addresses()->associate($address);
        $address = $user->addresses()->first();
        $user->addresses()->associate($address);
        $this->assertEquals(1, $user->addresses()->count());

        $user = User::where('name', 'John Doe')->first();
        $user->addresses()->associate($address);
        $this->assertEquals(1, $user->addresses()->count());

        $user->save();
        $user->addresses()->associate($address);
        $this->assertEquals(1, $user->addresses()->count());
    }

Jens Segers's avatar
Jens Segers committed
709 710
    public function testSaveEmptyModel()
    {
711
        $user = User::create(['name' => 'John Doe']);
Jens Segers's avatar
Jens Segers committed
712 713
        $user->addresses()->save(new Address);
        $this->assertNotNull($user->addresses);
Jens Segers's avatar
Jens Segers committed
714
        $this->assertEquals(1, $user->addresses()->count());
Jens Segers's avatar
Jens Segers committed
715 716
    }

Jens Segers's avatar
Jens Segers committed
717 718
    public function testIncrementEmbedded()
    {
719 720
        $user = User::create(['name' => 'John Doe']);
        $address = $user->addresses()->create(['city' => 'New York', 'visited' => 5]);
Jens Segers's avatar
Jens Segers committed
721 722 723 724 725 726 727

        $address->increment('visited');
        $this->assertEquals(6, $address->visited);
        $this->assertEquals(6, $user->addresses()->first()->visited);

        $user = User::where('name', 'John Doe')->first();
        $this->assertEquals(6, $user->addresses()->first()->visited);
728

729 730 731
        $user = User::where('name', 'John Doe')->first();
        $address = $user->addresses()->first();

732 733
        $address->decrement('visited');
        $this->assertEquals(5, $address->visited);
734
        $this->assertEquals(5, $user->addresses()->first()->visited);
735 736 737

        $user = User::where('name', 'John Doe')->first();
        $this->assertEquals(5, $user->addresses()->first()->visited);
Jens Segers's avatar
Jens Segers committed
738 739
    }

740 741
    public function testPaginateEmbedsMany()
    {
742 743 744 745
        $user = User::create(['name' => 'John Doe']);
        $user->addresses()->save(new Address(['city' => 'New York']));
        $user->addresses()->save(new Address(['city' => 'Paris']));
        $user->addresses()->save(new Address(['city' => 'Brussels']));
746 747 748

        $results = $user->addresses()->paginate(2);
        $this->assertEquals(2, $results->count());
749
        $this->assertEquals(3, $results->total());
750 751
    }

752
}