EmbeddedRelationsTest.php 32 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 24 25 26 27 28 29
        $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
        $events->shouldReceive('fire')->with('eloquent.retrieved: ' . get_class($address), anything());
        $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);

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

33 34
        $this->assertNotNull($user->addresses);
        $this->assertInstanceOf('Illuminate\Database\Eloquent\Collection', $user->addresses);
Pooya Parsa's avatar
Pooya Parsa committed
35
        $this->assertEquals(['London'], $user->addresses->pluck('city')->all());
36 37 38 39 40 41
        $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
42
        $this->assertInstanceOf('MongoDB\BSON\ObjectID', $raw['_id']);
43

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

        $user = User::find($user->_id);
Pooya Parsa's avatar
Pooya Parsa committed
47
        $this->assertEquals(['London', 'Paris'], $user->addresses->pluck('city')->all());
48

49 50 51 52 53 54 55
        $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
        $events->shouldReceive('fire')->with('eloquent.retrieved: ' . get_class($address), anything());
        $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);

56 57
        $address->city = 'New York';
        $user->addresses()->save($address);
58
        $address->unsetEventDispatcher();
59 60 61 62 63

        $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
64
        $this->assertEquals(['London', 'New York'], $user->addresses->pluck('city')->all());
65 66

        $freshUser = User::find($user->_id);
Pooya Parsa's avatar
Pooya Parsa committed
67
        $this->assertEquals(['London', 'New York'], $freshUser->addresses->pluck('city')->all());
68 69 70 71 72 73 74 75 76

        $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);
77
        $user->addresses()->save(new Address(['city' => 'Bruxelles']));
Pooya Parsa's avatar
Pooya Parsa committed
78
        $this->assertEquals(['London', 'New York', 'Bruxelles'], $user->addresses->pluck('city')->all());
79

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

        $freshUser = User::find($user->_id);
Pooya Parsa's avatar
Pooya Parsa committed
86
        $this->assertEquals(['London', 'Manhattan', 'Bruxelles'], $freshUser->addresses->pluck('city')->all());
87 88
    }

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

94 95 96 97 98
    //     $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);
99

100
    //     $address->save();
101

102 103 104 105 106
    //     $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);
107

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

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

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

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

127
        $user->addresses()->associate($address);
Pooya Parsa's avatar
Pooya Parsa committed
128
        $this->assertEquals(['London'], $user->addresses->pluck('city')->all());
129 130 131
        $this->assertNotNull($address->_id);

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

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

        $freshUser = User::find($user->_id);
Pooya Parsa's avatar
Pooya Parsa committed
139
        $this->assertEquals([], $freshUser->addresses->pluck('city')->all());
140 141 142 143
    }

    public function testEmbedsManySaveMany()
    {
144 145
        $user = User::create(['name' => 'John Doe']);
        $user->addresses()->saveMany([new Address(['city' => 'London']), new Address(['city' => 'Bristol'])]);
Pooya Parsa's avatar
Pooya Parsa committed
146
        $this->assertEquals(['London', 'Bristol'], $user->addresses->pluck('city')->all());
147 148

        $freshUser = User::find($user->id);
Pooya Parsa's avatar
Pooya Parsa committed
149
        $this->assertEquals(['London', 'Bristol'], $freshUser->addresses->pluck('city')->all());
150 151 152 153
    }

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

        $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
167
        $this->assertEquals(['Paris'], $user->addresses->pluck('city')->all());
168

169
        $user->addresses()->create(['_id' => $address->_id, 'city' => 'Bruxelles']);
170
        $this->assertEquals(1, $user->addresses->count());
Pooya Parsa's avatar
Pooya Parsa committed
171
        $this->assertEquals(['Bruxelles'], $user->addresses->pluck('city')->all());
172 173 174 175
    }

    public function testEmbedsManyCreate()
    {
176 177
        $user = User::create([]);
        $address = $user->addresses()->create(['city' => 'Bruxelles']);
178 179
        $this->assertInstanceOf('Address', $address);
        $this->assertTrue(is_string($address->_id));
Pooya Parsa's avatar
Pooya Parsa committed
180
        $this->assertEquals(['Bruxelles'], $user->addresses->pluck('city')->all());
181 182

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

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

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

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

    public function testEmbedsManyCreateMany()
    {
198 199
        $user = User::create([]);
        list($bruxelles, $paris) = $user->addresses()->createMany([['city' => 'Bruxelles'], ['city' => 'Paris']]);
200 201
        $this->assertInstanceOf('Address', $bruxelles);
        $this->assertEquals('Bruxelles', $bruxelles->city);
Pooya Parsa's avatar
Pooya Parsa committed
202
        $this->assertEquals(['Bruxelles', 'Paris'], $user->addresses->pluck('city')->all());
203 204

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

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

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

215 216 217 218 219
        $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
        $events->shouldReceive('fire')->with('eloquent.retrieved: ' . get_class($address), anything());
        $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'));

220
        $user->addresses()->destroy($address->_id);
Pooya Parsa's avatar
Pooya Parsa committed
221
        $this->assertEquals(['Bristol', 'Bruxelles'], $user->addresses->pluck('city')->all());
222

223 224
        $address->unsetEventDispatcher();

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

229 230
        $user->addresses()->create(['city' => 'Paris']);
        $user->addresses()->create(['city' => 'San Francisco']);
231 232

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

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

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

242 243
        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
244
        $this->assertEquals(['Bristol'], $user->addresses->pluck('city')->all());
Jens Segers's avatar
Jens Segers committed
245
    }
246

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

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

254 255 256 257 258
        $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
        $events->shouldReceive('fire')->with('eloquent.retrieved: ' . get_class($address), anything());
        $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'));

259 260 261 262 263
        $address->delete();

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

264 265
        $address->unsetEventDispatcher();

266 267 268 269 270 271 272 273
        $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());
    }

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

        $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()
    {
288 289
        $user = User::create(['name' => 'John Doe']);
        $address = new Address(['city' => 'London']);
290 291

        $address = $user->addresses()->attach($address);
Pooya Parsa's avatar
Pooya Parsa committed
292
        $this->assertEquals(['London'], $user->addresses->pluck('city')->all());
293 294

        $user->addresses()->detach($address);
Pooya Parsa's avatar
Pooya Parsa committed
295
        $this->assertEquals([], $user->addresses->pluck('city')->all());
296 297 298 299
    }

    public function testEmbedsManyCreatingEventReturnsFalse()
    {
300 301
        $user = User::create(['name' => 'John Doe']);
        $address = new Address(['city' => 'London']);
302

303 304 305 306
        $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
        $events->shouldReceive('fire')->with('eloquent.retrieved: ' . get_class($address), anything());
        $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);
307 308

        $this->assertFalse($user->addresses()->save($address));
309
        $address->unsetEventDispatcher();
310 311 312 313
    }

    public function testEmbedsManySavingEventReturnsFalse()
    {
314 315
        $user = User::create(['name' => 'John Doe']);
        $address = new Address(['city' => 'Paris']);
316 317
        $address->exists = true;

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

        $this->assertFalse($user->addresses()->save($address));
323
        $address->unsetEventDispatcher();
324 325 326 327
    }

    public function testEmbedsManyUpdatingEventReturnsFalse()
    {
328 329
        $user = User::create(['name' => 'John Doe']);
        $address = new Address(['city' => 'New York']);
330 331
        $user->addresses()->save($address);

332 333 334 335
        $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
        $events->shouldReceive('fire')->with('eloquent.retrieved: ' . get_class($address), anything());
        $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);
336 337 338 339

        $address->city = 'Warsaw';

        $this->assertFalse($user->addresses()->save($address));
340
        $address->unsetEventDispatcher();
341 342 343 344
    }

    public function testEmbedsManyDeletingEventReturnsFalse()
    {
345 346
        $user = User::create(['name' => 'John Doe']);
        $user->addresses()->save(new Address(['city' => 'New York']));
347 348 349

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

350 351 352
        $address->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
        $events->shouldReceive('fire')->with('eloquent.retrieved: ' . get_class($address), anything());
        $events->shouldReceive('until')->once()->with('eloquent.deleting: ' . get_class($address), Mockery::mustBe($address))->andReturn(false);
353 354

        $this->assertEquals(0, $user->addresses()->destroy($address));
Pooya Parsa's avatar
Pooya Parsa committed
355
        $this->assertEquals(['New York'], $user->addresses->pluck('city')->all());
356 357

        $address->unsetEventDispatcher();
358 359 360 361
    }

    public function testEmbedsManyFindOrContains()
    {
362 363 364
        $user = User::create(['name' => 'John Doe']);
        $address1 = $user->addresses()->save(new Address(['city' => 'New York']));
        $address2 = $user->addresses()->save(new Address(['city' => 'Paris']));
365 366 367 368 369 370 371 372 373 374 375 376 377

        $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()
    {
378 379 380
        $user1 = User::create(['name' => 'John Doe']);
        $user1->addresses()->save(new Address(['city' => 'New York']));
        $user1->addresses()->save(new Address(['city' => 'Paris']));
381

382 383 384
        $user2 = User::create(['name' => 'Jane Doe']);
        $user2->addresses()->save(new Address(['city' => 'Berlin']));
        $user2->addresses()->save(new Address(['city' => 'Paris']));
385 386 387 388

        $user = User::find($user1->id);
        $relations = $user->getRelations();
        $this->assertFalse(array_key_exists('addresses', $relations));
389 390
        $this->assertArrayHasKey('addresses', $user->toArray());
        $this->assertTrue(is_array($user->toArray()['addresses']));
391 392 393 394 395

        $user = User::with('addresses')->get()->first();
        $relations = $user->getRelations();
        $this->assertTrue(array_key_exists('addresses', $relations));
        $this->assertEquals(2, $relations['addresses']->count());
396
        $this->assertArrayHasKey('addresses', $user->toArray());
397
        $this->assertTrue(is_array($user->toArray()['addresses']));
398 399
    }

400
    public function testEmbedsManyDeleteAll()
401
    {
402 403 404
        $user1 = User::create(['name' => 'John Doe']);
        $user1->addresses()->save(new Address(['city' => 'New York']));
        $user1->addresses()->save(new Address(['city' => 'Paris']));
405

406 407 408
        $user2 = User::create(['name' => 'Jane Doe']);
        $user2->addresses()->save(new Address(['city' => 'Berlin']));
        $user2->addresses()->save(new Address(['city' => 'Paris']));
409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425

        $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()
    {
426 427 428 429 430
        $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')]));
431

Pooya Parsa's avatar
Pooya Parsa committed
432 433 434 435 436
        $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());
437

438
        $results = $user->addresses->first();
439 440
        $this->assertInstanceOf('Address', $results);

441 442
        $results = $user->addresses()->where('country', 'Belgium');
        $this->assertInstanceOf('Illuminate\Database\Eloquent\Collection', $results);
443 444
        $this->assertEquals(3, $results->count());

445
        $results = $user->addresses()->whereIn('visited', [7, 13]);
446
        $this->assertEquals(2, $results->count());
447 448 449 450
    }

    public function testEmbedsOne()
    {
451 452
        $user = User::create(['name' => 'John Doe']);
        $father = new User(['name' => 'Mark Doe']);
453

454 455 456 457 458 459 460
        $father->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
        $events->shouldReceive('fire')->with('eloquent.retrieved: ' . get_class($father), anything());
        $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);

461
        $father = $user->father()->save($father);
462
        $father->unsetEventDispatcher();
463

464
        $this->assertNotNull($user->father);
465 466 467 468 469 470 471
        $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
472
        $this->assertInstanceOf('MongoDB\BSON\ObjectID', $raw['_id']);
473

474 475 476 477 478 479 480
        $father->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
        $events->shouldReceive('fire')->with('eloquent.retrieved: ' . get_class($father), anything());
        $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);

481 482
        $father->name = 'Tom Doe';
        $user->father()->save($father);
483
        $father->unsetEventDispatcher();
484

485
        $this->assertNotNull($user->father);
486 487
        $this->assertEquals('Tom Doe', $user->father->name);

488
        $father = new User(['name' => 'Jim Doe']);
489

490 491 492 493 494 495 496
        $father->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
        $events->shouldReceive('fire')->with('eloquent.retrieved: ' . get_class($father), anything());
        $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);

497
        $father = $user->father()->save($father);
498
        $father->unsetEventDispatcher();
499

500
        $this->assertNotNull($user->father);
501 502 503
        $this->assertEquals('Jim Doe', $user->father->name);
    }

504 505
    public function testEmbedsOneAssociate()
    {
506 507
        $user = User::create(['name' => 'John Doe']);
        $father = new User(['name' => 'Mark Doe']);
508

509 510 511 512
        $father->setEventDispatcher($events = Mockery::mock('Illuminate\Events\Dispatcher'));
        $events->shouldReceive('fire')->with('eloquent.retrieved: ' . get_class($father), anything());
        $events->shouldReceive('until')->times(0)->with('eloquent.saving: ' . get_class($father), $father);

513
        $father = $user->father()->associate($father);
514
        $father->unsetEventDispatcher();
515

516
        $this->assertNotNull($user->father);
517 518 519
        $this->assertEquals('Mark Doe', $user->father->name);
    }

Jens Segers's avatar
Jens Segers committed
520 521 522 523 524 525
    public function testEmbedsOneNullAssociation()
    {
        $user = User::create();
        $this->assertNull($user->father);
    }

526 527
    public function testEmbedsOneDelete()
    {
528 529
        $user = User::create(['name' => 'John Doe']);
        $father = $user->father()->save(new User(['name' => 'Mark Doe']));
530 531 532 533 534

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

535 536
    public function testEmbedsManyToArray()
    {
537 538 539 540
        $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']));
541 542

        $array = $user->toArray();
543 544
        $this->assertArrayHasKey('addresses', $array);
        $this->assertTrue(is_array($array['addresses']));
545 546
    }

547 548
    public function testEmbeddedSave()
    {
549 550 551
        $user = User::create(['name' => 'John Doe']);
        $address = $user->addresses()->create(['city' => 'New York']);
        $father = $user->father()->create(['name' => 'Mark Doe']);
552 553 554 555 556 557 558 559 560 561 562 563 564

        $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
565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580

        $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);
581 582
    }

583 584
    public function testNestedEmbedsOne()
    {
585 586 587 588
        $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']);
589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612

        $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()
    {
613 614 615 616 617 618
        $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']);
619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634

        $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()
    {
635 636 637 638
        $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']);
639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655

        $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
656 657
    public function testDoubleAssociate()
    {
658 659
        $user = User::create(['name' => 'John Doe']);
        $address = new Address(['city' => 'Paris']);
Jens Segers's avatar
Jens Segers committed
660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675

        $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
676 677
    public function testSaveEmptyModel()
    {
678
        $user = User::create(['name' => 'John Doe']);
Jens Segers's avatar
Jens Segers committed
679 680
        $user->addresses()->save(new Address);
        $this->assertNotNull($user->addresses);
Jens Segers's avatar
Jens Segers committed
681
        $this->assertEquals(1, $user->addresses()->count());
Jens Segers's avatar
Jens Segers committed
682 683
    }

Jens Segers's avatar
Jens Segers committed
684 685
    public function testIncrementEmbedded()
    {
686 687
        $user = User::create(['name' => 'John Doe']);
        $address = $user->addresses()->create(['city' => 'New York', 'visited' => 5]);
Jens Segers's avatar
Jens Segers committed
688 689 690 691 692 693 694

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

696 697 698
        $user = User::where('name', 'John Doe')->first();
        $address = $user->addresses()->first();

699 700
        $address->decrement('visited');
        $this->assertEquals(5, $address->visited);
701
        $this->assertEquals(5, $user->addresses()->first()->visited);
702 703 704

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

707 708
    public function testPaginateEmbedsMany()
    {
709 710 711 712
        $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']));
713 714 715

        $results = $user->addresses()->paginate(2);
        $this->assertEquals(2, $results->count());
716
        $this->assertEquals(3, $results->total());
717
    }
718
}