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

3
class RelationsTest extends TestCase {
unknown's avatar
unknown committed
4 5 6

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

9 10 11 12 13
        User::truncate();
        Book::truncate();
        Item::truncate();
        Role::truncate();
        Client::truncate();
14
        Group::truncate();
Jens Segers's avatar
Jens Segers committed
15
        Photo::truncate();
unknown's avatar
unknown committed
16 17
    }

18
    public function testHasMany()
unknown's avatar
unknown committed
19
    {
20 21 22
        $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
23

24 25
        $books = $author->books;
        $this->assertEquals(2, count($books));
unknown's avatar
unknown committed
26

27 28 29 30 31
        $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
32

33 34
        $items = $user->items;
        $this->assertEquals(3, count($items));
35
    }
unknown's avatar
unknown committed
36 37 38

    public function testBelongsTo()
    {
39 40 41
        $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
42

43 44
        $author = $book->author;
        $this->assertEquals('George R. R. Martin', $author->name);
unknown's avatar
unknown committed
45

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

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

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

58 59
        $role = $user->role;
        $this->assertEquals('admin', $role->type);
Jens Segers's avatar
Jens Segers committed
60 61 62 63 64 65 66 67 68 69 70 71 72 73
        $this->assertEquals($user->_id, $role->user_id);

        $user = User::create(array('name' => 'Jane Doe'));
        $role = new Role(array('type' => 'user'));
        $user->role()->save($role);

        $role = $user->role;
        $this->assertEquals('user', $role->type);
        $this->assertEquals($user->_id, $role->user_id);

        $user = User::where('name', 'Jane Doe')->first();
        $role = $user->role;
        $this->assertEquals('user', $role->type);
        $this->assertEquals($user->_id, $role->user_id);
unknown's avatar
unknown committed
74 75 76 77
    }

    public function testWithBelongsTo()
    {
78 79 80 81 82 83
        $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
84
        $items = Item::with('user')->orderBy('user_id', 'desc')->get();
85 86 87 88 89 90

        $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
91 92 93 94
    }

    public function testWithHashMany()
    {
95 96 97 98 99
        $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
100

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

103 104 105
        $items = $user->getRelation('items');
        $this->assertEquals(3, count($items));
        $this->assertInstanceOf('Item', $items[0]);
unknown's avatar
unknown committed
106 107 108 109
    }

    public function testWithHasOne()
    {
110 111 112
        $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
113

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

116 117 118
        $role = $user->getRelation('role');
        $this->assertInstanceOf('Role', $role);
        $this->assertEquals('admin', $role->type);
unknown's avatar
unknown committed
119 120 121 122
    }

    public function testEasyRelation()
    {
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
        // 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);
    }

144
    public function testBelongsToMany()
145 146 147
    {
        $user = User::create(array('name' => 'John Doe'));

148
        // Add 2 clients
149 150 151
        $user->clients()->save(new Client(array('name' => 'Pork Pies Ltd.')));
        $user->clients()->create(array('name' => 'Buffet Bar Inc.'));

152
        // Refetch
153 154 155
        $user = User::with('clients')->find($user->_id);
        $client = Client::with('users')->first();

156 157 158 159
        // Check for relation attributes
        $this->assertTrue(array_key_exists('user_ids', $client->getAttributes()));
        $this->assertTrue(array_key_exists('client_ids', $user->getAttributes()));

160
        $clients = $user->getRelation('clients');
161
        $users = $client->getRelation('users');
162 163 164

        $this->assertInstanceOf('Illuminate\Database\Eloquent\Collection', $users);
        $this->assertInstanceOf('Illuminate\Database\Eloquent\Collection', $clients);
165 166
        $this->assertInstanceOf('Client', $clients[0]);
        $this->assertInstanceOf('User', $users[0]);
167 168 169 170
        $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
171
        $user = $client->users()->create(array('name' => 'Jane Doe'));
172

Jens Segers's avatar
Jens Segers committed
173 174 175
        $this->assertInstanceOf('Illuminate\Database\Eloquent\Collection', $user->clients);
        $this->assertInstanceOf('Client', $user->clients->first());
        $this->assertCount(1, $user->clients);
176

Jens Segers's avatar
Jens Segers committed
177
        // Get user and unattached client
178 179 180 181 182 183 184 185 186 187
        $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
188 189
        $this->assertCount(1, $user->clients);
        $this->assertCount(1, $client->users);
190 191 192 193 194 195 196 197 198 199 200

        // 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
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
        $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);
216 217
    }

218
    public function testBelongsToManyAttachesExistingModels()
219 220 221 222 223 224 225 226 227
    {
        $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
228 229
            Client::create(array('name' => 'synced Boloni Ltd.'))->_id,
            Client::create(array('name' => 'synced Meatballs Inc.'))->_id
230 231 232 233 234 235 236 237 238 239 240 241 242
        );

        // 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
243
        // Add more clients
244 245
        $user->clients()->sync($moreClients);

246
        // Refetch
247 248
        $user = User::with('clients')->find($user->_id);

unknown's avatar
unknown committed
249 250
        // Assert there are now still 2 client objects in the relationship
        $this->assertCount(2, $user->clients);
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274

        // 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
275
    }
Jens Segers's avatar
Jens Segers committed
276 277 278 279 280 281 282

    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'));
283 284
        $photo = $user->photos()->save($photo);

Jens Segers's avatar
Jens Segers committed
285 286 287
        $this->assertEquals(1, $user->photos->count());
        $this->assertEquals($photo->id, $user->photos->first()->id);

Jens Segers's avatar
Jens Segers committed
288 289 290 291
        $user = User::find($user->_id);
        $this->assertEquals(1, $user->photos->count());
        $this->assertEquals($photo->id, $user->photos->first()->id);

Jens Segers's avatar
Jens Segers committed
292 293
        $photo = Photo::create(array('url' => 'http://graph.facebook.com/jane.doe/picture'));
        $client->photo()->save($photo);
Jens Segers's avatar
Jens Segers committed
294

Jens Segers's avatar
Jens Segers committed
295 296
        $this->assertNotNull($client->photo);
        $this->assertEquals($photo->id, $client->photo->id);
Jens Segers's avatar
Jens Segers committed
297 298

        $client = Client::find($client->_id);
Jens Segers's avatar
Jens Segers committed
299 300
        $this->assertNotNull($client->photo);
        $this->assertEquals($photo->id, $client->photo->id);
Jens Segers's avatar
Jens Segers committed
301 302 303

        $photo = Photo::first();
        $this->assertEquals($photo->imageable->name, $user->name);
Jens Segers's avatar
Jens Segers committed
304 305 306 307 308

        $user = User::with('photos')->find($user->_id);
        $relations = $user->getRelations();
        $this->assertTrue(array_key_exists('photos', $relations));
        $this->assertEquals(1, $relations['photos']->count());
309 310 311 312 313 314 315 316 317

        $photos = Photo::with('imageable')->get();
        $relations = $photos[0]->getRelations();
        $this->assertTrue(array_key_exists('imageable', $relations));
        $this->assertInstanceOf('User', $relations['imageable']);

        $relations = $photos[1]->getRelations();
        $this->assertTrue(array_key_exists('imageable', $relations));
        $this->assertInstanceOf('Client', $relations['imageable']);
318
    }
319

320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
    public function testHasManyHas()
    {
        $author1 = User::create(array('name' => 'George R. R. Martin'));
        $author1->books()->create(array('title' => 'A Game of Thrones', 'rating' => 5));
        $author1->books()->create(array('title' => 'A Clash of Kings', 'rating' => 5));
        $author2 = User::create(array('name' => 'John Doe'));
        $author2->books()->create(array('title' => 'My book', 'rating' => 2));
        User::create(array('name' => 'Anonymous author'));
        Book::create(array('title' => 'Anonymous book', 'rating' => 1));

        $authors = User::has('books')->get();
        $this->assertCount(2, $authors);
        $this->assertEquals('George R. R. Martin', $authors[0]->name);
        $this->assertEquals('John Doe', $authors[1]->name);

        $authors = User::has('books', '>', 1)->get();
        $this->assertCount(1, $authors);

        $authors = User::has('books', '<', 5)->get();
        $this->assertCount(3, $authors);

        $authors = User::has('books', '>=', 2)->get();
        $this->assertCount(1, $authors);

        $authors = User::has('books', '<=', 1)->get();
        $this->assertCount(2, $authors);

        $authors = User::has('books', '=', 2)->get();
        $this->assertCount(1, $authors);

        $authors = User::has('books', '!=', 2)->get();
        $this->assertCount(2, $authors);

        $authors = User::has('books', '=', 0)->get();
        $this->assertCount(1, $authors);

        $authors = User::has('books', '!=', 0)->get();
        $this->assertCount(2, $authors);

        $authors = User::whereHas('books', function($query)
        {
            $query->where('rating', 5);

        })->get();
        $this->assertCount(1, $authors);

        $authors = User::whereHas('books', function($query)
        {
            $query->where('rating', '<', 5);

        })->get();
        $this->assertCount(1, $authors);
    }

    public function testHasOneHas()
    {
        $user1 = User::create(array('name' => 'John Doe'));
        $user1->role()->create(array('title' => 'admin'));
        $user2 = User::create(array('name' => 'Jane Doe'));
        $user2->role()->create(array('title' => 'reseller'));
        User::create(array('name' => 'Mark Moe'));
        Role::create(array('title' => 'Customer'));

        $users = User::has('role')->get();
        $this->assertCount(2, $users);
        $this->assertEquals('John Doe', $users[0]->name);
        $this->assertEquals('Jane Doe', $users[1]->name);

        $users = User::has('role', '=', 0)->get();
        $this->assertCount(1, $users);

        $users = User::has('role', '!=', 0)->get();
        $this->assertCount(2, $users);
    }

395
}