EmbeddedRelationsTest.php 30.8 KB
Newer Older
1 2
<?php

Jens Segers's avatar
Jens Segers committed
3 4
class EmbeddedRelationsTest extends TestCase
{
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
    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);
Pooya Parsa's avatar
Pooya Parsa committed
34
        $this->assertEquals(['London'], $user->addresses->pluck('city')->all());
35 36 37 38 39 40
        $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();
Jens Segers's avatar
Jens Segers committed
41
        $this->assertInstanceOf('MongoDB\BSON\ObjectID', $raw['_id']);
42

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

        $user = User::find($user->_id);
Pooya Parsa's avatar
Pooya Parsa committed
46
        $this->assertEquals(['London', 'Paris'], $user->addresses->pluck('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());
Pooya Parsa's avatar
Pooya Parsa committed
62
        $this->assertEquals(['London', 'New York'], $user->addresses->pluck('city')->all());
63 64

        $freshUser = User::find($user->_id);
Pooya Parsa's avatar
Pooya Parsa committed
65
        $this->assertEquals(['London', 'New York'], $freshUser->addresses->pluck('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']));
Pooya Parsa's avatar
Pooya Parsa committed
76
        $this->assertEquals(['London', 'New York', 'Bruxelles'], $user->addresses->pluck('city')->all());
77

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

        $freshUser = User::find($user->_id);
Pooya Parsa's avatar
Pooya Parsa committed
84
        $this->assertEquals(['London', 'Manhattan', 'Bruxelles'], $freshUser->addresses->pluck('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);
Pooya Parsa's avatar
Pooya Parsa committed
126
        $this->assertEquals(['London'], $user->addresses->pluck('city')->all());
127 128 129
        $this->assertNotNull($address->_id);

        $freshUser = User::find($user->_id);
Pooya Parsa's avatar
Pooya Parsa committed
130
        $this->assertEquals([], $freshUser->addresses->pluck('city')->all());
131 132 133

        $address->city = 'Londinium';
        $user->addresses()->associate($address);
Pooya Parsa's avatar
Pooya Parsa committed
134
        $this->assertEquals(['Londinium'], $user->addresses->pluck('city')->all());
135 136

        $freshUser = User::find($user->_id);
Pooya Parsa's avatar
Pooya Parsa committed
137
        $this->assertEquals([], $freshUser->addresses->pluck('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'])]);
Pooya Parsa's avatar
Pooya Parsa committed
144
        $this->assertEquals(['London', 'Bristol'], $user->addresses->pluck('city')->all());
145 146

        $freshUser = User::find($user->id);
Pooya Parsa's avatar
Pooya Parsa committed
147
        $this->assertEquals(['London', 'Bristol'], $freshUser->addresses->pluck('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());
Pooya Parsa's avatar
Pooya Parsa committed
157
        $this->assertEquals(['London'], $user->addresses->pluck('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());
Pooya Parsa's avatar
Pooya Parsa committed
165
        $this->assertEquals(['Paris'], $user->addresses->pluck('city')->all());
166

167
        $user->addresses()->create(['_id' => $address->_id, 'city' => 'Bruxelles']);
168
        $this->assertEquals(1, $user->addresses->count());
Pooya Parsa's avatar
Pooya Parsa committed
169
        $this->assertEquals(['Bruxelles'], $user->addresses->pluck('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));
Pooya Parsa's avatar
Pooya Parsa committed
178
        $this->assertEquals(['Bruxelles'], $user->addresses->pluck('city')->all());
179 180

        $raw = $address->getAttributes();
Jens Segers's avatar
Jens Segers committed
181
        $this->assertInstanceOf('MongoDB\BSON\ObjectID', $raw['_id']);
182 183

        $freshUser = User::find($user->id);
Pooya Parsa's avatar
Pooya Parsa committed
184
        $this->assertEquals(['Bruxelles'], $freshUser->addresses->pluck('city')->all());
185

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

        $raw = $address->getAttributes();
Jens Segers's avatar
Jens Segers committed
191
        $this->assertInstanceOf('MongoDB\BSON\ObjectID', $raw['_id']);
192 193 194 195
    }

    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);
Pooya Parsa's avatar
Pooya Parsa committed
200
        $this->assertEquals(['Bruxelles', 'Paris'], $user->addresses->pluck('city')->all());
201 202

        $freshUser = User::find($user->id);
Pooya Parsa's avatar
Pooya Parsa committed
203
        $this->assertEquals(['Bruxelles', 'Paris'], $freshUser->addresses->pluck('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);
Pooya Parsa's avatar
Pooya Parsa committed
218
        $this->assertEquals(['Bristol', 'Bruxelles'], $user->addresses->pluck('city')->all());
219 220 221 222 223

        $address->unsetEventDispatcher();

        $address = $user->addresses->first();
        $user->addresses()->destroy($address);
Pooya Parsa's avatar
Pooya Parsa committed
224
        $this->assertEquals(['Bruxelles'], $user->addresses->pluck('city')->all());
225

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

        $freshUser = User::find($user->id);
Pooya Parsa's avatar
Pooya Parsa committed
230
        $this->assertEquals(['Bruxelles', 'Paris', 'San Francisco'], $freshUser->addresses->pluck('city')->all());
231

Pooya Parsa's avatar
Pooya Parsa committed
232
        $ids = $user->addresses->pluck('_id');
233
        $user->addresses()->destroy($ids);
Pooya Parsa's avatar
Pooya Parsa committed
234
        $this->assertEquals([], $user->addresses->pluck('city')->all());
235 236

        $freshUser = User::find($user->id);
Pooya Parsa's avatar
Pooya Parsa committed
237
        $this->assertEquals([], $freshUser->addresses->pluck('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]);
Pooya Parsa's avatar
Pooya Parsa committed
241
        $this->assertEquals(['Bristol'], $user->addresses->pluck('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);
Pooya Parsa's avatar
Pooya Parsa committed
288
        $this->assertEquals(['London'], $user->addresses->pluck('city')->all());
289 290

        $user->addresses()->detach($address);
Pooya Parsa's avatar
Pooya Parsa committed
291
        $this->assertEquals([], $user->addresses->pluck('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));
Pooya Parsa's avatar
Pooya Parsa committed
347
        $this->assertEquals(['New York'], $user->addresses->pluck('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

Pooya Parsa's avatar
Pooya Parsa committed
424 425 426 427 428
        $this->assertEquals(['Paris', 'Bruges', 'Brussels', 'Ghent'], $user->addresses()->pluck('city')->all());
        $this->assertEquals(['Bruges', 'Brussels', 'Ghent', 'Paris'], $user->addresses()->sortBy('city')->pluck('city')->all());
        $this->assertEquals([], $user->addresses()->where('city', 'New York')->pluck('city')->all());
        $this->assertEquals(['Bruges', 'Brussels', 'Ghent'], $user->addresses()->where('country', 'Belgium')->pluck('city')->all());
        $this->assertEquals(['Bruges', 'Brussels', 'Ghent'], $user->addresses()->where('country', 'Belgium')->sortBy('city')->pluck('city')->all());
429

430
        $results = $user->addresses->first();
431 432
        $this->assertInstanceOf('Address', $results);

433 434
        $results = $user->addresses()->where('country', 'Belgium');
        $this->assertInstanceOf('Illuminate\Database\Eloquent\Collection', $results);
435 436
        $this->assertEquals(3, $results->count());

437
        $results = $user->addresses()->whereIn('visited', [7, 13]);
438
        $this->assertEquals(2, $results->count());
439 440 441 442
    }

    public function testEmbedsOne()
    {
443 444
        $user = User::create(['name' => 'John Doe']);
        $father = new User(['name' => 'Mark Doe']);
445 446

        $father->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
447 448 449 450
        $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);
451 452 453 454

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

455
        $this->assertNotNull($user->father);
456 457 458 459 460 461 462
        $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();
Jens Segers's avatar
Jens Segers committed
463
        $this->assertInstanceOf('MongoDB\BSON\ObjectID', $raw['_id']);
464 465

        $father->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
466 467 468 469
        $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);
470 471 472 473 474

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

475
        $this->assertNotNull($user->father);
476 477
        $this->assertEquals('Tom Doe', $user->father->name);

478
        $father = new User(['name' => 'Jim Doe']);
479 480

        $father->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
481 482 483 484
        $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);
485 486 487 488

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

489
        $this->assertNotNull($user->father);
490 491 492
        $this->assertEquals('Jim Doe', $user->father->name);
    }

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

        $father->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
499
        $events->shouldReceive('until')->times(0)->with('eloquent.saving: ' . get_class($father), $father);
500 501 502 503

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

504
        $this->assertNotNull($user->father);
505 506 507
        $this->assertEquals('Mark Doe', $user->father->name);
    }

Jens Segers's avatar
Jens Segers committed
508 509 510 511 512 513
    public function testEmbedsOneNullAssociation()
    {
        $user = User::create();
        $this->assertNull($user->father);
    }

514 515
    public function testEmbedsOneDelete()
    {
516 517
        $user = User::create(['name' => 'John Doe']);
        $father = $user->father()->save(new User(['name' => 'Mark Doe']));
518 519 520 521 522

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

523 524
    public function testEmbedsManyToArray()
    {
525 526 527 528
        $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']));
529 530

        $array = $user->toArray();
531 532
        $this->assertArrayHasKey('addresses', $array);
        $this->assertTrue(is_array($array['addresses']));
533 534
    }

535 536
    public function testEmbeddedSave()
    {
537 538 539
        $user = User::create(['name' => 'John Doe']);
        $address = $user->addresses()->create(['city' => 'New York']);
        $father = $user->father()->create(['name' => 'Mark Doe']);
540 541 542 543 544 545 546 547 548 549 550 551 552

        $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
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568

        $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);
569 570
    }

571 572
    public function testNestedEmbedsOne()
    {
573 574 575 576
        $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']);
577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600

        $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()
    {
601 602 603 604 605 606
        $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']);
607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622

        $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()
    {
623 624 625 626
        $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']);
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643

        $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
644 645
    public function testDoubleAssociate()
    {
646 647
        $user = User::create(['name' => 'John Doe']);
        $address = new Address(['city' => 'Paris']);
Jens Segers's avatar
Jens Segers committed
648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663

        $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
664 665
    public function testSaveEmptyModel()
    {
666
        $user = User::create(['name' => 'John Doe']);
Jens Segers's avatar
Jens Segers committed
667 668
        $user->addresses()->save(new Address);
        $this->assertNotNull($user->addresses);
Jens Segers's avatar
Jens Segers committed
669
        $this->assertEquals(1, $user->addresses()->count());
Jens Segers's avatar
Jens Segers committed
670 671
    }

Jens Segers's avatar
Jens Segers committed
672 673
    public function testIncrementEmbedded()
    {
674 675
        $user = User::create(['name' => 'John Doe']);
        $address = $user->addresses()->create(['city' => 'New York', 'visited' => 5]);
Jens Segers's avatar
Jens Segers committed
676 677 678 679 680 681 682

        $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);
683

684 685 686
        $user = User::where('name', 'John Doe')->first();
        $address = $user->addresses()->first();

687 688
        $address->decrement('visited');
        $this->assertEquals(5, $address->visited);
689
        $this->assertEquals(5, $user->addresses()->first()->visited);
690 691 692

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

695 696
    public function testPaginateEmbedsMany()
    {
697 698 699 700
        $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']));
701 702 703

        $results = $user->addresses()->paginate(2);
        $this->assertEquals(2, $results->count());
704
        $this->assertEquals(3, $results->total());
705
    }
706
}