RelationsTest.php 17.4 KB
Newer Older
Jens Segers's avatar
Jens Segers committed
1 2
<?php

3 4
use Illuminate\Database\Eloquent\Collection;

Jens Segers's avatar
Jens Segers committed
5 6
class RelationsTest extends PHPUnit_Framework_TestCase {

7
    public function setUp() {
unknown's avatar
unknown committed
8 9 10 11
    }

    public function tearDown()
    {
12 13 14 15 16
        User::truncate();
        Book::truncate();
        Item::truncate();
        Role::truncate();
        Client::truncate();
17
        Group::truncate();
Jens Segers's avatar
Jens Segers committed
18
        Photo::truncate();
unknown's avatar
unknown committed
19 20
    }

21
    public function testHasMany()
unknown's avatar
unknown committed
22
    {
23 24 25
        $author = User::create(array('name' => 'George R. R. Martin'));
        Book::create(array('title' => 'A Game of Thrones', 'author_id' => $author->_id));
        Book::create(array('title' => 'A Clash of Kings', 'author_id' => $author->_id));
unknown's avatar
unknown committed
26

27 28
        $books = $author->books;
        $this->assertEquals(2, count($books));
unknown's avatar
unknown committed
29

30 31 32 33 34
        $user = User::create(array('name' => 'John Doe'));
        Item::create(array('type' => 'knife', 'user_id' => $user->_id));
        Item::create(array('type' => 'shield', 'user_id' => $user->_id));
        Item::create(array('type' => 'sword', 'user_id' => $user->_id));
        Item::create(array('type' => 'bag', 'user_id' => null));
unknown's avatar
unknown committed
35

36 37
        $items = $user->items;
        $this->assertEquals(3, count($items));
38
    }
unknown's avatar
unknown committed
39 40 41

    public function testBelongsTo()
    {
42 43 44
        $user = User::create(array('name' => 'George R. R. Martin'));
        Book::create(array('title' => 'A Game of Thrones', 'author_id' => $user->_id));
        $book = Book::create(array('title' => 'A Clash of Kings', 'author_id' => $user->_id));
unknown's avatar
unknown committed
45

46 47
        $author = $book->author;
        $this->assertEquals('George R. R. Martin', $author->name);
unknown's avatar
unknown committed
48

49 50
        $user = User::create(array('name' => 'John Doe'));
        $item = Item::create(array('type' => 'sword', 'user_id' => $user->_id));
unknown's avatar
unknown committed
51

52 53
        $owner = $item->user;
        $this->assertEquals('John Doe', $owner->name);
unknown's avatar
unknown committed
54 55 56 57
    }

    public function testHasOne()
    {
58 59
        $user = User::create(array('name' => 'John Doe'));
        Role::create(array('type' => 'admin', 'user_id' => $user->_id));
unknown's avatar
unknown committed
60

61 62
        $role = $user->role;
        $this->assertEquals('admin', $role->type);
unknown's avatar
unknown committed
63 64 65 66
    }

    public function testWithBelongsTo()
    {
67 68 69 70 71 72
        $user = User::create(array('name' => 'John Doe'));
        Item::create(array('type' => 'knife', 'user_id' => $user->_id));
        Item::create(array('type' => 'shield', 'user_id' => $user->_id));
        Item::create(array('type' => 'sword', 'user_id' => $user->_id));
        Item::create(array('type' => 'bag', 'user_id' => null));

Alexandre Butynski's avatar
Alexandre Butynski committed
73
        $items = Item::with('user')->orderBy('user_id', 'desc')->get();
74 75 76 77 78 79

        $user = $items[0]->getRelation('user');
        $this->assertInstanceOf('User', $user);
        $this->assertEquals('John Doe', $user->name);
        $this->assertEquals(1, count($items[0]->getRelations()));
        $this->assertEquals(null, $items[3]->getRelation('user'));
unknown's avatar
unknown committed
80 81 82 83
    }

    public function testWithHashMany()
    {
84 85 86 87 88
        $user = User::create(array('name' => 'John Doe'));
        Item::create(array('type' => 'knife', 'user_id' => $user->_id));
        Item::create(array('type' => 'shield', 'user_id' => $user->_id));
        Item::create(array('type' => 'sword', 'user_id' => $user->_id));
        Item::create(array('type' => 'bag', 'user_id' => null));
unknown's avatar
unknown committed
89

90
        $user = User::with('items')->find($user->_id);
unknown's avatar
unknown committed
91

92 93 94
        $items = $user->getRelation('items');
        $this->assertEquals(3, count($items));
        $this->assertInstanceOf('Item', $items[0]);
unknown's avatar
unknown committed
95 96 97 98
    }

    public function testWithHasOne()
    {
99 100 101
        $user = User::create(array('name' => 'John Doe'));
        Role::create(array('type' => 'admin', 'user_id' => $user->_id));
        Role::create(array('type' => 'guest', 'user_id' => $user->_id));
unknown's avatar
unknown committed
102

103
        $user = User::with('role')->find($user->_id);
unknown's avatar
unknown committed
104

105 106 107
        $role = $user->getRelation('role');
        $this->assertInstanceOf('Role', $role);
        $this->assertEquals('admin', $role->type);
unknown's avatar
unknown committed
108 109 110 111
    }

    public function testEasyRelation()
    {
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
        // Has Many
        $user = User::create(array('name' => 'John Doe'));
        $item = Item::create(array('type' => 'knife'));
        $user->items()->save($item);

        $user = User::find($user->_id);
        $items = $user->items;
        $this->assertEquals(1, count($items));
        $this->assertInstanceOf('Item', $items[0]);

        // Has one
        $user = User::create(array('name' => 'John Doe'));
        $role = Role::create(array('type' => 'admin'));
        $user->role()->save($role);

        $user = User::find($user->_id);
        $role = $user->role;
        $this->assertInstanceOf('Role', $role);
        $this->assertEquals('admin', $role->type);
    }

133
    public function testBelongsToMany()
134 135 136
    {
        $user = User::create(array('name' => 'John Doe'));

137
        // Add 2 clients
138 139 140
        $user->clients()->save(new Client(array('name' => 'Pork Pies Ltd.')));
        $user->clients()->create(array('name' => 'Buffet Bar Inc.'));

141
        // Refetch
142 143 144
        $user = User::with('clients')->find($user->_id);
        $client = Client::with('users')->first();

145 146 147 148
        // Check for relation attributes
        $this->assertTrue(array_key_exists('user_ids', $client->getAttributes()));
        $this->assertTrue(array_key_exists('client_ids', $user->getAttributes()));

149 150
        $users = $client->getRelation('users');
        $clients = $user->getRelation('clients');
151 152 153

        $this->assertInstanceOf('Illuminate\Database\Eloquent\Collection', $users);
        $this->assertInstanceOf('Illuminate\Database\Eloquent\Collection', $clients);
154 155
        $this->assertInstanceOf('Client', $clients[0]);
        $this->assertInstanceOf('User', $users[0]);
156 157 158 159
        $this->assertCount(2, $user->clients);
        $this->assertCount(1, $client->users);

        // Now create a new user to an existing client
Jens Segers's avatar
Jens Segers committed
160
        $user = $client->users()->create(array('name' => 'Jane Doe'));
161

Jens Segers's avatar
Jens Segers committed
162 163 164
        $this->assertInstanceOf('Illuminate\Database\Eloquent\Collection', $user->clients);
        $this->assertInstanceOf('Client', $user->clients->first());
        $this->assertCount(1, $user->clients);
165

Jens Segers's avatar
Jens Segers committed
166
        // Get user and unattached client
167 168 169 170 171 172 173 174 175 176
        $user = User::where('name', '=', 'Jane Doe')->first();
        $client = Client::Where('name', '=', 'Buffet Bar Inc.')->first();

        // Check the models are what they should be
        $this->assertInstanceOf('Client', $client);
        $this->assertInstanceOf('User', $user);

        // Assert they are not attached
        $this->assertFalse(in_array($client->_id, $user->client_ids));
        $this->assertFalse(in_array($user->_id, $client->user_ids));
Jens Segers's avatar
Jens Segers committed
177 178
        $this->assertCount(1, $user->clients);
        $this->assertCount(1, $client->users);
179 180 181 182 183 184 185 186 187 188 189

        // Attach the client to the user
        $user->clients()->attach($client);

        // Get the new user model
        $user = User::where('name', '=', 'Jane Doe')->first();
        $client = Client::Where('name', '=', 'Buffet Bar Inc.')->first();

        // Assert they are attached
        $this->assertTrue(in_array($client->_id, $user->client_ids));
        $this->assertTrue(in_array($user->_id, $client->user_ids));
Jens Segers's avatar
Jens Segers committed
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
        $this->assertCount(2, $user->clients);
        $this->assertCount(2, $client->users);

        // Detach clients from user
        $user->clients()->sync(array());

        // Get the new user model
        $user = User::where('name', '=', 'Jane Doe')->first();
        $client = Client::Where('name', '=', 'Buffet Bar Inc.')->first();

        // Assert they are not attached
        $this->assertFalse(in_array($client->_id, $user->client_ids));
        $this->assertFalse(in_array($user->_id, $client->user_ids));
        $this->assertCount(0, $user->clients);
        $this->assertCount(1, $client->users);
205 206
    }

207
    public function testBelongsToManyAttachesExistingModels()
208 209 210 211 212 213 214 215 216
    {
        $user = User::create(array('name' => 'John Doe', 'client_ids' => array('1234523')));

        $clients = array(
            Client::create(array('name' => 'Pork Pies Ltd.'))->_id,
            Client::create(array('name' => 'Buffet Bar Inc.'))->_id
        );

        $moreClients = array(
unknown's avatar
unknown committed
217 218
            Client::create(array('name' => 'synced Boloni Ltd.'))->_id,
            Client::create(array('name' => 'synced Meatballs Inc.'))->_id
219 220 221 222 223 224 225 226 227 228 229 230 231
        );

        // Sync multiple records
        $user->clients()->sync($clients);

        $user = User::with('clients')->find($user->_id);

        // Assert non attached ID's are detached succesfully
        $this->assertFalse(in_array('1234523', $user->client_ids));

        // Assert there are two client objects in the relationship
        $this->assertCount(2, $user->clients);

Jens Segers's avatar
Jens Segers committed
232
        // Add more clients
233 234
        $user->clients()->sync($moreClients);

235
        // Refetch
236 237
        $user = User::with('clients')->find($user->_id);

unknown's avatar
unknown committed
238 239
        // Assert there are now still 2 client objects in the relationship
        $this->assertCount(2, $user->clients);
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263

        // Assert that the new relationships name start with synced
        $this->assertStringStartsWith('synced', $user->clients[0]->name);
        $this->assertStringStartsWith('synced', $user->clients[1]->name);
    }

    public function testBelongsToManyCustom()
    {
        $user = User::create(array('name' => 'John Doe'));
        $group = $user->groups()->create(array('name' => 'Admins'));

        // Refetch
        $user = User::find($user->_id);
        $group = Group::find($group->_id);

        // Check for custom relation attributes
        $this->assertTrue(array_key_exists('users', $group->getAttributes()));
        $this->assertTrue(array_key_exists('groups', $user->getAttributes()));

        // Assert they are attached
        $this->assertTrue(in_array($group->_id, $user->groups));
        $this->assertTrue(in_array($user->_id, $group->users));
        $this->assertEquals($group->_id, $user->groups()->first()->_id);
        $this->assertEquals($user->_id, $group->users()->first()->_id);
unknown's avatar
unknown committed
264
    }
Jens Segers's avatar
Jens Segers committed
265 266 267 268 269 270 271

    public function testMorph()
    {
        $user = User::create(array('name' => 'John Doe'));
        $client = Client::create(array('name' => 'Jane Doe'));

        $photo = Photo::create(array('url' => 'http://graph.facebook.com/john.doe/picture'));
272 273
        $photo = $user->photos()->save($photo);

Jens Segers's avatar
Jens Segers committed
274 275 276 277 278 279 280 281 282 283
        $this->assertEquals(1, $user->photos->count());
        $this->assertEquals($photo->id, $user->photos->first()->id);

        $photo = Photo::create(array('url' => 'http://graph.facebook.com/john.doe/picture'));
        $client->photos()->save($photo);
        $this->assertEquals(1, $client->photos->count());
        $this->assertEquals($photo->id, $client->photos->first()->id);

        $photo = Photo::first();
        $this->assertEquals($photo->imageable->name, $user->name);
284
    }
285

286
    public function testEmbedsManySave()
287 288
    {
        $user = User::create(array('name' => 'John Doe'));
289
        $address = new Address(array('city' => 'London'));
290

291
        $address = $user->addresses()->save($address);
292
        $this->assertNotNull($user->_addresses);
293 294 295
        $this->assertEquals(array('London'), $user->addresses->lists('city'));
        $this->assertInstanceOf('DateTime', $address->created_at);
        $this->assertInstanceOf('DateTime', $address->updated_at);
296
        $this->assertNotNull($address->_id);
297

298
        $address = $user->addresses()->save(new Address(array('city' => 'Paris')));
299

300 301
        $user = User::find($user->_id);
        $this->assertEquals(array('London', 'Paris'), $user->addresses->lists('city'));
302 303

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

306 307 308 309 310 311
        $this->assertEquals(2, count($user->addresses));
        $this->assertEquals(2, count($user->addresses()->get()));
        $this->assertEquals(2, $user->addresses->count());
        $this->assertEquals(array('London', 'New York'), $user->addresses->lists('city'));

        $freshUser = User::find($user->_id);
312 313
        $this->assertEquals(array('London', 'New York'), $freshUser->addresses->lists('city'));

314
        $address = $user->addresses->first();
315 316 317 318
        $this->assertEquals('London', $address->city);
        $this->assertInstanceOf('DateTime', $address->created_at);
        $this->assertInstanceOf('DateTime', $address->updated_at);
        $this->assertInstanceOf('User', $address->user);
319 320 321 322 323 324 325 326 327 328 329

        $user = User::find($user->_id);
        $user->addresses()->save(new Address(array('city' => 'Bruxelles')));
        $this->assertEquals(array('London', 'New York', 'Bruxelles'), $user->addresses->lists('city'));
        $address = $user->addresses[1];
        $address->city = "Manhattan";
        $user->addresses()->save($address);
        $this->assertEquals(array('London', 'Manhattan', 'Bruxelles'), $user->addresses->lists('city'));

        $freshUser = User::find($user->_id);
        $this->assertEquals(array('London', 'Manhattan', 'Bruxelles'), $freshUser->addresses->lists('city'));
330 331
    }

332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
    public function testEmbedsManyAssociate()
    {
        $user = User::create(array('name' => 'John Doe'));
        $address = new Address(array('city' => 'London'));

        $address = $user->addresses()->associate($address);
        $this->assertNotNull($user->_addresses);
        $this->assertEquals(array('London'), $user->addresses->lists('city'));
        $this->assertNotNull($address->_id);

        $freshUser = User::find($user->_id);
        $this->assertEquals(array(), $freshUser->addresses->lists('city'));

        $address->city = 'Londinium';
        $user->addresses()->associate($address);
        $this->assertEquals(array('Londinium'), $user->addresses->lists('city'));

        $freshUser = User::find($user->_id);
        $this->assertEquals(array(), $freshUser->addresses->lists('city'));
    }

353
    public function testEmbedsManySaveMany()
354 355
    {
        $user = User::create(array('name' => 'John Doe'));
356 357
        $user->addresses()->saveMany(array(new Address(array('city' => 'London')), new Address(array('city' => 'Bristol'))));
        $this->assertEquals(array('London', 'Bristol'), $user->addresses->lists('city'));
358 359

        $freshUser = User::find($user->id);
360 361
        $this->assertEquals(array('London', 'Bristol'), $freshUser->addresses->lists('city'));
    }
362

363 364
    public function testEmbedsManyCreate()
    {
365 366 367 368
        $user = User::create(array());
        $address = $user->addresses()->create(array('city' => 'Bruxelles'));
        $this->assertInstanceOf('Address', $address);
        $this->assertInstanceOf('MongoID', $address->_id);
369
        $this->assertEquals(array('Bruxelles'), $user->addresses->lists('city'));
370

371 372
        $freshUser = User::find($user->id);
        $this->assertEquals(array('Bruxelles'), $freshUser->addresses->lists('city'));
373 374 375 376

        $user = User::create(array());
        $address = $user->addresses()->create(array('_id' => '', 'city' => 'Bruxelles'));
        $this->assertInstanceOf('MongoID', $address->_id);
377 378
    }

379 380 381 382 383 384 385 386 387 388 389 390
    public function testEmbedsManyCreateMany()
    {
        $user = User::create(array());
        list($bruxelles, $paris) = $user->addresses()->createMany(array(array('city' => 'Bruxelles'), array('city' => 'Paris')));
        $this->assertInstanceOf('Address', $bruxelles);
        $this->assertEquals('Bruxelles', $bruxelles->city);
        $this->assertEquals(array('Bruxelles', 'Paris'), $user->addresses->lists('city'));

        $freshUser = User::find($user->id);
        $this->assertEquals(array('Bruxelles', 'Paris'), $freshUser->addresses->lists('city'));
    }

391
    public function testEmbedsManyDestroy()
392
    {
393 394 395 396 397 398
        $user = User::create(array('name' => 'John Doe'));
        $user->addresses()->saveMany(array(new Address(array('city' => 'London')), new Address(array('city' => 'Bristol')), new Address(array('city' => 'Bruxelles'))));

        $address = $user->addresses->first();
        $user->addresses()->destroy($address->_id);
        $this->assertEquals(array('Bristol', 'Bruxelles'), $user->addresses->lists('city'));
399 400 401 402

        $address = $user->addresses->first();
        $user->addresses()->destroy($address);
        $this->assertEquals(array('Bruxelles'), $user->addresses->lists('city'));
403 404 405 406

        $user->addresses()->create(array('city' => 'Paris'));
        $user->addresses()->create(array('city' => 'San Francisco'));

407 408
        $freshUser = User::find($user->id);
        $this->assertEquals(array('Bruxelles', 'Paris', 'San Francisco'), $freshUser->addresses->lists('city'));
409 410 411 412 413 414 415

        $ids = $user->addresses->lists('_id');
        $user->addresses()->destroy($ids);
        $this->assertEquals(array(), $user->addresses->lists('city'));

        $freshUser = User::find($user->id);
        $this->assertEquals(array(), $freshUser->addresses->lists('city'));
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431

        list($london, $bristol, $bruxelles) = $user->addresses()->saveMany(array(new Address(array('city' => 'London')), new Address(array('city' => 'Bristol')), new Address(array('city' => 'Bruxelles'))));
        $user->addresses()->destroy(array($london, $bruxelles));
        $this->assertEquals(array('Bristol'), $user->addresses->lists('city'));
    }

    public function testEmbedsManyDissociate()
    {
        $user = User::create(array());
        $cordoba = $user->addresses()->create(array('city' => 'Cordoba'));

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

        $freshUser = User::find($user->id);
        $this->assertEquals(0, $user->addresses->count());
        $this->assertEquals(1, $freshUser->addresses->count());
432 433 434 435 436 437 438 439 440 441 442 443
    }

    public function testEmbedsManyAliases()
    {
        $user = User::create(array('name' => 'John Doe'));
        $address = new Address(array('city' => 'London'));

        $address = $user->addresses()->attach($address);
        $this->assertEquals(array('London'), $user->addresses->lists('city'));

        $user->addresses()->detach($address);
        $this->assertEquals(array(), $user->addresses->lists('city'));
444 445
    }

446
}