ModelTest.php 17.5 KB
Newer Older
Jens Segers's avatar
Jens Segers committed
1
<?php
Simon Schaufelberger's avatar
Simon Schaufelberger committed
2
declare(strict_types=1);
Jens Segers's avatar
Jens Segers committed
3

Jens Segers's avatar
Jens Segers committed
4 5
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
Simon Schaufelberger's avatar
Simon Schaufelberger committed
6
use Illuminate\Database\Eloquent\ModelNotFoundException;
Jens Segers's avatar
Jens Segers committed
7 8 9 10
use Jenssegers\Mongodb\Eloquent\Model;
use MongoDB\BSON\ObjectID;
use MongoDB\BSON\UTCDateTime;

Jens Segers's avatar
Jens Segers committed
11 12
class ModelTest extends TestCase
{
Stas's avatar
Stas committed
13
    public function tearDown(): void
Jens Segers's avatar
Jens Segers committed
14 15 16 17 18 19 20
    {
        User::truncate();
        Soft::truncate();
        Book::truncate();
        Item::truncate();
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
21
    public function testNewModel(): void
Jens Segers's avatar
Jens Segers committed
22 23
    {
        $user = new User;
Jens Segers's avatar
Jens Segers committed
24
        $this->assertInstanceOf(Model::class, $user);
Simon Schaufelberger's avatar
Simon Schaufelberger committed
25
        $this->assertInstanceOf(\Jenssegers\Mongodb\Connection::class, $user->getConnection());
Gabriel Caruso's avatar
Gabriel Caruso committed
26
        $this->assertFalse($user->exists);
Jens Segers's avatar
Jens Segers committed
27 28 29 30
        $this->assertEquals('users', $user->getTable());
        $this->assertEquals('_id', $user->getKeyName());
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
31
    public function testInsert(): void
Jens Segers's avatar
Jens Segers committed
32 33 34 35 36 37 38 39
    {
        $user = new User;
        $user->name = 'John Doe';
        $user->title = 'admin';
        $user->age = 35;

        $user->save();

Gabriel Caruso's avatar
Gabriel Caruso committed
40
        $this->assertTrue($user->exists);
Jens Segers's avatar
Jens Segers committed
41 42 43
        $this->assertEquals(1, User::count());

        $this->assertTrue(isset($user->_id));
44
        $this->assertIsString($user->_id);
Jens Segers's avatar
Jens Segers committed
45 46
        $this->assertNotEquals('', (string) $user->_id);
        $this->assertNotEquals(0, strlen((string) $user->_id));
Jens Segers's avatar
Jens Segers committed
47
        $this->assertInstanceOf(Carbon::class, $user->created_at);
Jens Segers's avatar
Jens Segers committed
48 49

        $raw = $user->getAttributes();
Jens Segers's avatar
Jens Segers committed
50
        $this->assertInstanceOf(ObjectID::class, $raw['_id']);
Jens Segers's avatar
Jens Segers committed
51 52 53 54 55

        $this->assertEquals('John Doe', $user->name);
        $this->assertEquals(35, $user->age);
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
56
    public function testUpdate(): void
Jens Segers's avatar
Jens Segers committed
57 58 59 60 61 62 63 64
    {
        $user = new User;
        $user->name = 'John Doe';
        $user->title = 'admin';
        $user->age = 35;
        $user->save();

        $raw = $user->getAttributes();
Jens Segers's avatar
Jens Segers committed
65
        $this->assertInstanceOf(ObjectID::class, $raw['_id']);
Jens Segers's avatar
Jens Segers committed
66

Simon Schaufelberger's avatar
Simon Schaufelberger committed
67
        /** @var User $check */
Jens Segers's avatar
Jens Segers committed
68 69 70 71
        $check = User::find($user->_id);
        $check->age = 36;
        $check->save();

Gabriel Caruso's avatar
Gabriel Caruso committed
72
        $this->assertTrue($check->exists);
Jens Segers's avatar
Jens Segers committed
73 74
        $this->assertInstanceOf(Carbon::class, $check->created_at);
        $this->assertInstanceOf(Carbon::class, $check->updated_at);
Jens Segers's avatar
Jens Segers committed
75 76 77 78 79 80 81 82
        $this->assertEquals(1, User::count());

        $this->assertEquals('John Doe', $check->name);
        $this->assertEquals(36, $check->age);

        $user->update(['age' => 20]);

        $raw = $user->getAttributes();
Jens Segers's avatar
Jens Segers committed
83
        $this->assertInstanceOf(ObjectID::class, $raw['_id']);
Jens Segers's avatar
Jens Segers committed
84 85 86 87 88

        $check = User::find($user->_id);
        $this->assertEquals(20, $check->age);
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
89
    public function testManualStringId(): void
Jens Segers's avatar
Jens Segers committed
90 91 92 93 94 95 96 97
    {
        $user = new User;
        $user->_id = '4af9f23d8ead0e1d32000000';
        $user->name = 'John Doe';
        $user->title = 'admin';
        $user->age = 35;
        $user->save();

Gabriel Caruso's avatar
Gabriel Caruso committed
98
        $this->assertTrue($user->exists);
Jens Segers's avatar
Jens Segers committed
99 100 101
        $this->assertEquals('4af9f23d8ead0e1d32000000', $user->_id);

        $raw = $user->getAttributes();
Jens Segers's avatar
Jens Segers committed
102
        $this->assertInstanceOf(ObjectID::class, $raw['_id']);
Jens Segers's avatar
Jens Segers committed
103 104 105 106 107 108 109 110

        $user = new User;
        $user->_id = 'customId';
        $user->name = 'John Doe';
        $user->title = 'admin';
        $user->age = 35;
        $user->save();

Gabriel Caruso's avatar
Gabriel Caruso committed
111
        $this->assertTrue($user->exists);
Jens Segers's avatar
Jens Segers committed
112 113 114
        $this->assertEquals('customId', $user->_id);

        $raw = $user->getAttributes();
115
        $this->assertIsString($raw['_id']);
Jens Segers's avatar
Jens Segers committed
116 117
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
118
    public function testManualIntId(): void
Jens Segers's avatar
Jens Segers committed
119 120 121 122 123 124 125 126
    {
        $user = new User;
        $user->_id = 1;
        $user->name = 'John Doe';
        $user->title = 'admin';
        $user->age = 35;
        $user->save();

Gabriel Caruso's avatar
Gabriel Caruso committed
127
        $this->assertTrue($user->exists);
Jens Segers's avatar
Jens Segers committed
128 129 130
        $this->assertEquals(1, $user->_id);

        $raw = $user->getAttributes();
131
        $this->assertIsInt($raw['_id']);
Jens Segers's avatar
Jens Segers committed
132 133
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
134
    public function testDelete(): void
Jens Segers's avatar
Jens Segers committed
135 136 137 138 139 140 141
    {
        $user = new User;
        $user->name = 'John Doe';
        $user->title = 'admin';
        $user->age = 35;
        $user->save();

Gabriel Caruso's avatar
Gabriel Caruso committed
142
        $this->assertTrue($user->exists);
Jens Segers's avatar
Jens Segers committed
143 144 145 146 147 148 149
        $this->assertEquals(1, User::count());

        $user->delete();

        $this->assertEquals(0, User::count());
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
150
    public function testAll(): void
Jens Segers's avatar
Jens Segers committed
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
    {
        $user = new User;
        $user->name = 'John Doe';
        $user->title = 'admin';
        $user->age = 35;
        $user->save();

        $user = new User;
        $user->name = 'Jane Doe';
        $user->title = 'user';
        $user->age = 32;
        $user->save();

        $all = User::all();

Gabriel Caruso's avatar
Gabriel Caruso committed
166
        $this->assertCount(2, $all);
Pooya Parsa's avatar
Pooya Parsa committed
167 168
        $this->assertContains('John Doe', $all->pluck('name'));
        $this->assertContains('Jane Doe', $all->pluck('name'));
Jens Segers's avatar
Jens Segers committed
169 170
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
171
    public function testFind(): void
Jens Segers's avatar
Jens Segers committed
172 173 174 175 176 177 178
    {
        $user = new User;
        $user->name = 'John Doe';
        $user->title = 'admin';
        $user->age = 35;
        $user->save();

Simon Schaufelberger's avatar
Simon Schaufelberger committed
179
        /** @var User $check */
Jens Segers's avatar
Jens Segers committed
180 181
        $check = User::find($user->_id);

Jens Segers's avatar
Jens Segers committed
182
        $this->assertInstanceOf(Model::class, $check);
Gabriel Caruso's avatar
Gabriel Caruso committed
183
        $this->assertTrue($check->exists);
Jens Segers's avatar
Jens Segers committed
184 185 186 187 188 189
        $this->assertEquals($user->_id, $check->_id);

        $this->assertEquals('John Doe', $check->name);
        $this->assertEquals(35, $check->age);
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
190
    public function testGet(): void
Jens Segers's avatar
Jens Segers committed
191 192 193 194 195 196 197
    {
        User::insert([
            ['name' => 'John Doe'],
            ['name' => 'Jane Doe'],
        ]);

        $users = User::get();
Gabriel Caruso's avatar
Gabriel Caruso committed
198
        $this->assertCount(2, $users);
Jens Segers's avatar
Jens Segers committed
199 200
        $this->assertInstanceOf(Collection::class, $users);
        $this->assertInstanceOf(Model::class, $users[0]);
Jens Segers's avatar
Jens Segers committed
201 202
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
203
    public function testFirst(): void
Jens Segers's avatar
Jens Segers committed
204 205 206 207 208 209
    {
        User::insert([
            ['name' => 'John Doe'],
            ['name' => 'Jane Doe'],
        ]);

Simon Schaufelberger's avatar
Simon Schaufelberger committed
210
        /** @var User $user */
Jens Segers's avatar
Jens Segers committed
211
        $user = User::first();
Jens Segers's avatar
Jens Segers committed
212
        $this->assertInstanceOf(Model::class, $user);
Jens Segers's avatar
Jens Segers committed
213 214 215
        $this->assertEquals('John Doe', $user->name);
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
216
    public function testNoDocument(): void
Jens Segers's avatar
Jens Segers committed
217 218
    {
        $items = Item::where('name', 'nothing')->get();
Jens Segers's avatar
Jens Segers committed
219
        $this->assertInstanceOf(Collection::class, $items);
Jens Segers's avatar
Jens Segers committed
220 221 222
        $this->assertEquals(0, $items->count());

        $item = Item::where('name', 'nothing')->first();
Gabriel Caruso's avatar
Gabriel Caruso committed
223
        $this->assertNull($item);
Jens Segers's avatar
Jens Segers committed
224 225

        $item = Item::find('51c33d8981fec6813e00000a');
Gabriel Caruso's avatar
Gabriel Caruso committed
226
        $this->assertNull($item);
Jens Segers's avatar
Jens Segers committed
227 228
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
229
    public function testFindOrFail(): void
Jens Segers's avatar
Jens Segers committed
230
    {
Simon Schaufelberger's avatar
Simon Schaufelberger committed
231 232
        $this->expectException(ModelNotFoundException::class);
        User::findOrFail('51c33d8981fec6813e00000a');
Jens Segers's avatar
Jens Segers committed
233 234
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
235
    public function testCreate(): void
Jens Segers's avatar
Jens Segers committed
236
    {
Simon Schaufelberger's avatar
Simon Schaufelberger committed
237
        /** @var User $user */
Jens Segers's avatar
Jens Segers committed
238 239
        $user = User::create(['name' => 'Jane Poe']);

Jens Segers's avatar
Jens Segers committed
240
        $this->assertInstanceOf(Model::class, $user);
Gabriel Caruso's avatar
Gabriel Caruso committed
241
        $this->assertTrue($user->exists);
Jens Segers's avatar
Jens Segers committed
242 243
        $this->assertEquals('Jane Poe', $user->name);

Simon Schaufelberger's avatar
Simon Schaufelberger committed
244
        /** @var User $check */
Jens Segers's avatar
Jens Segers committed
245
        $check = User::where('name', 'Jane Poe')->first();
246
        $this->assertEquals($user->_id, $check->_id);
Jens Segers's avatar
Jens Segers committed
247 248
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
249
    public function testDestroy(): void
Jens Segers's avatar
Jens Segers committed
250 251 252 253 254 255 256 257 258 259 260 261
    {
        $user = new User;
        $user->name = 'John Doe';
        $user->title = 'admin';
        $user->age = 35;
        $user->save();

        User::destroy((string) $user->_id);

        $this->assertEquals(0, User::count());
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
262
    public function testTouch(): void
Jens Segers's avatar
Jens Segers committed
263 264 265 266 267 268 269 270 271 272
    {
        $user = new User;
        $user->name = 'John Doe';
        $user->title = 'admin';
        $user->age = 35;
        $user->save();

        $old = $user->updated_at;
        sleep(1);
        $user->touch();
Simon Schaufelberger's avatar
Simon Schaufelberger committed
273 274

        /** @var User $check */
Jens Segers's avatar
Jens Segers committed
275 276 277 278 279
        $check = User::find($user->_id);

        $this->assertNotEquals($old, $check->updated_at);
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
280
    public function testSoftDelete(): void
Jens Segers's avatar
Jens Segers committed
281 282 283 284 285 286
    {
        Soft::create(['name' => 'John Doe']);
        Soft::create(['name' => 'Jane Doe']);

        $this->assertEquals(2, Soft::count());

Simon Schaufelberger's avatar
Simon Schaufelberger committed
287
        /** @var Soft $user */
Jens Segers's avatar
Jens Segers committed
288
        $user = Soft::where('name', 'John Doe')->first();
Gabriel Caruso's avatar
Gabriel Caruso committed
289 290
        $this->assertTrue($user->exists);
        $this->assertFalse($user->trashed());
Jens Segers's avatar
Jens Segers committed
291 292 293
        $this->assertNull($user->deleted_at);

        $user->delete();
Gabriel Caruso's avatar
Gabriel Caruso committed
294
        $this->assertTrue($user->trashed());
Jens Segers's avatar
Jens Segers committed
295 296 297 298 299 300 301 302 303 304
        $this->assertNotNull($user->deleted_at);

        $user = Soft::where('name', 'John Doe')->first();
        $this->assertNull($user);

        $this->assertEquals(1, Soft::count());
        $this->assertEquals(2, Soft::withTrashed()->count());

        $user = Soft::withTrashed()->where('name', 'John Doe')->first();
        $this->assertNotNull($user);
Jens Segers's avatar
Jens Segers committed
305
        $this->assertInstanceOf(Carbon::class, $user->deleted_at);
Gabriel Caruso's avatar
Gabriel Caruso committed
306
        $this->assertTrue($user->trashed());
Jens Segers's avatar
Jens Segers committed
307 308 309 310 311

        $user->restore();
        $this->assertEquals(2, Soft::count());
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
312
    public function testPrimaryKey(): void
Jens Segers's avatar
Jens Segers committed
313 314 315 316 317 318 319 320 321 322 323 324 325
    {
        $user = new User;
        $this->assertEquals('_id', $user->getKeyName());

        $book = new Book;
        $this->assertEquals('title', $book->getKeyName());

        $book->title = 'A Game of Thrones';
        $book->author = 'George R. R. Martin';
        $book->save();

        $this->assertEquals('A Game of Thrones', $book->getKey());

Simon Schaufelberger's avatar
Simon Schaufelberger committed
326
        /** @var Book $check */
Jens Segers's avatar
Jens Segers committed
327 328 329 330 331 332
        $check = Book::find('A Game of Thrones');
        $this->assertEquals('title', $check->getKeyName());
        $this->assertEquals('A Game of Thrones', $check->getKey());
        $this->assertEquals('A Game of Thrones', $check->title);
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
333
    public function testScope(): void
Jens Segers's avatar
Jens Segers committed
334 335 336 337 338 339 340 341 342 343
    {
        Item::insert([
            ['name' => 'knife', 'type' => 'sharp'],
            ['name' => 'spoon', 'type' => 'round'],
        ]);

        $sharp = Item::sharp()->get();
        $this->assertEquals(1, $sharp->count());
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
344
    public function testToArray(): void
Jens Segers's avatar
Jens Segers committed
345 346 347 348
    {
        $item = Item::create(['name' => 'fork', 'type' => 'sharp']);

        $array = $item->toArray();
Jens Segers's avatar
Jens Segers committed
349 350
        $keys = array_keys($array);
        sort($keys);
Jens Segers's avatar
Jens Segers committed
351
        $this->assertEquals(['_id', 'created_at', 'name', 'type', 'updated_at'], $keys);
352 353 354
        $this->assertIsString($array['created_at']);
        $this->assertIsString($array['updated_at']);
        $this->assertIsString($array['_id']);
Jens Segers's avatar
Jens Segers committed
355 356
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
357
    public function testUnset(): void
Jens Segers's avatar
Jens Segers committed
358 359 360 361 362 363
    {
        $user1 = User::create(['name' => 'John Doe', 'note1' => 'ABC', 'note2' => 'DEF']);
        $user2 = User::create(['name' => 'Jane Doe', 'note1' => 'ABC', 'note2' => 'DEF']);

        $user1->unset('note1');

Gabriel Caruso's avatar
Gabriel Caruso committed
364
        $this->assertObjectNotHasAttribute('note1', $user1);
Jens Segers's avatar
Jens Segers committed
365 366 367 368 369 370 371 372
        $this->assertTrue(isset($user1->note2));
        $this->assertTrue(isset($user2->note1));
        $this->assertTrue(isset($user2->note2));

        // Re-fetch to be sure
        $user1 = User::find($user1->_id);
        $user2 = User::find($user2->_id);

Gabriel Caruso's avatar
Gabriel Caruso committed
373
        $this->assertObjectNotHasAttribute('note1', $user1);
Jens Segers's avatar
Jens Segers committed
374 375 376 377 378 379
        $this->assertTrue(isset($user1->note2));
        $this->assertTrue(isset($user2->note1));
        $this->assertTrue(isset($user2->note2));

        $user2->unset(['note1', 'note2']);

Gabriel Caruso's avatar
Gabriel Caruso committed
380 381
        $this->assertObjectNotHasAttribute('note1', $user2);
        $this->assertObjectNotHasAttribute('note2', $user2);
Jens Segers's avatar
Jens Segers committed
382 383
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
384
    public function testDates(): void
Jens Segers's avatar
Jens Segers committed
385 386 387
    {
        $birthday = new DateTime('1980/1/1');
        $user = User::create(['name' => 'John Doe', 'birthday' => $birthday]);
Jens Segers's avatar
Jens Segers committed
388
        $this->assertInstanceOf(Carbon::class, $user->birthday);
Jens Segers's avatar
Jens Segers committed
389 390

        $check = User::find($user->_id);
Jens Segers's avatar
Jens Segers committed
391
        $this->assertInstanceOf(Carbon::class, $check->birthday);
Jens Segers's avatar
Jens Segers committed
392 393 394 395 396 397 398
        $this->assertEquals($user->birthday, $check->birthday);

        $user = User::where('birthday', '>', new DateTime('1975/1/1'))->first();
        $this->assertEquals('John Doe', $user->name);

        // test custom date format for json output
        $json = $user->toArray();
399 400
        $this->assertEquals($user->birthday->format('l jS \of F Y h:i:s A'), $json['birthday']);
        $this->assertEquals($user->created_at->format('l jS \of F Y h:i:s A'), $json['created_at']);
Jens Segers's avatar
Jens Segers committed
401

Jens Segers's avatar
Jens Segers committed
402 403 404 405 406 407
        // test created_at
        $item = Item::create(['name' => 'sword']);
        $this->assertInstanceOf(UTCDateTime::class, $item->getOriginal('created_at'));
        $this->assertEquals($item->getOriginal('created_at')
            ->toDateTime()
            ->getTimestamp(), $item->created_at->getTimestamp());
Gabriel Caruso's avatar
Gabriel Caruso committed
408
        $this->assertLessThan(2, abs(time() - $item->created_at->getTimestamp()));
Jens Segers's avatar
Jens Segers committed
409

Jens Segers's avatar
Jens Segers committed
410
        // test default date format for json output
Simon Schaufelberger's avatar
Simon Schaufelberger committed
411
        /** @var Item $item */
Jens Segers's avatar
Jens Segers committed
412 413 414 415
        $item = Item::create(['name' => 'sword']);
        $json = $item->toArray();
        $this->assertEquals($item->created_at->format('Y-m-d H:i:s'), $json['created_at']);

Simon Schaufelberger's avatar
Simon Schaufelberger committed
416
        /** @var User $user */
Jens Segers's avatar
Jens Segers committed
417
        $user = User::create(['name' => 'Jane Doe', 'birthday' => time()]);
Jens Segers's avatar
Jens Segers committed
418
        $this->assertInstanceOf(Carbon::class, $user->birthday);
Jens Segers's avatar
Jens Segers committed
419 420

        $user = User::create(['name' => 'Jane Doe', 'birthday' => 'Monday 8th of August 2005 03:12:46 PM']);
Jens Segers's avatar
Jens Segers committed
421
        $this->assertInstanceOf(Carbon::class, $user->birthday);
Jens Segers's avatar
Jens Segers committed
422 423

        $user = User::create(['name' => 'Jane Doe', 'birthday' => '2005-08-08']);
Jens Segers's avatar
Jens Segers committed
424
        $this->assertInstanceOf(Carbon::class, $user->birthday);
Jens Segers's avatar
Jens Segers committed
425 426

        $user = User::create(['name' => 'Jane Doe', 'entry' => ['date' => '2005-08-08']]);
Jens Segers's avatar
Jens Segers committed
427
        $this->assertInstanceOf(Carbon::class, $user->getAttribute('entry.date'));
Jens Segers's avatar
Jens Segers committed
428 429

        $user->setAttribute('entry.date', new DateTime);
Jens Segers's avatar
Jens Segers committed
430
        $this->assertInstanceOf(Carbon::class, $user->getAttribute('entry.date'));
Jens Segers's avatar
Jens Segers committed
431 432

        $data = $user->toArray();
Jens Segers's avatar
Jens Segers committed
433
        $this->assertNotInstanceOf(UTCDateTime::class, $data['entry']['date']);
Jens Segers's avatar
Jens Segers committed
434
        $this->assertEquals((string) $user->getAttribute('entry.date')->format('Y-m-d H:i:s'), $data['entry']['date']);
Jens Segers's avatar
Jens Segers committed
435 436
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
437
    public function testIdAttribute(): void
Jens Segers's avatar
Jens Segers committed
438
    {
Simon Schaufelberger's avatar
Simon Schaufelberger committed
439
        /** @var User $user */
Jens Segers's avatar
Jens Segers committed
440 441 442 443 444 445 446
        $user = User::create(['name' => 'John Doe']);
        $this->assertEquals($user->id, $user->_id);

        $user = User::create(['id' => 'custom_id', 'name' => 'John Doe']);
        $this->assertNotEquals($user->id, $user->_id);
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
447
    public function testPushPull(): void
Jens Segers's avatar
Jens Segers committed
448
    {
Simon Schaufelberger's avatar
Simon Schaufelberger committed
449
        /** @var User $user */
Jens Segers's avatar
Jens Segers committed
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
        $user = User::create(['name' => 'John Doe']);

        $user->push('tags', 'tag1');
        $user->push('tags', ['tag1', 'tag2']);
        $user->push('tags', 'tag2', true);

        $this->assertEquals(['tag1', 'tag1', 'tag2'], $user->tags);
        $user = User::where('_id', $user->_id)->first();
        $this->assertEquals(['tag1', 'tag1', 'tag2'], $user->tags);

        $user->pull('tags', 'tag1');

        $this->assertEquals(['tag2'], $user->tags);
        $user = User::where('_id', $user->_id)->first();
        $this->assertEquals(['tag2'], $user->tags);

        $user->push('tags', 'tag3');
        $user->pull('tags', ['tag2', 'tag3']);

        $this->assertEquals([], $user->tags);
        $user = User::where('_id', $user->_id)->first();
        $this->assertEquals([], $user->tags);
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
474
    public function testRaw(): void
Jens Segers's avatar
Jens Segers committed
475 476 477 478 479
    {
        User::create(['name' => 'John Doe', 'age' => 35]);
        User::create(['name' => 'Jane Doe', 'age' => 35]);
        User::create(['name' => 'Harry Hoe', 'age' => 15]);

Simon Schaufelberger's avatar
Simon Schaufelberger committed
480
        $users = User::raw(function (\Jenssegers\Mongodb\Collection $collection) {
Jens Segers's avatar
Jens Segers committed
481 482
            return $collection->find(['age' => 35]);
        });
Jens Segers's avatar
Jens Segers committed
483 484
        $this->assertInstanceOf(Collection::class, $users);
        $this->assertInstanceOf(Model::class, $users[0]);
Jens Segers's avatar
Jens Segers committed
485

Simon Schaufelberger's avatar
Simon Schaufelberger committed
486
        $user = User::raw(function (\Jenssegers\Mongodb\Collection $collection) {
Jens Segers's avatar
Jens Segers committed
487 488
            return $collection->findOne(['age' => 35]);
        });
489

Jens Segers's avatar
Jens Segers committed
490
        $this->assertInstanceOf(Model::class, $user);
Jens Segers's avatar
Jens Segers committed
491

Simon Schaufelberger's avatar
Simon Schaufelberger committed
492
        $count = User::raw(function (\Jenssegers\Mongodb\Collection $collection) {
Jens Segers's avatar
Jens Segers committed
493 494 495 496
            return $collection->count();
        });
        $this->assertEquals(3, $count);

Simon Schaufelberger's avatar
Simon Schaufelberger committed
497
        $result = User::raw(function (\Jenssegers\Mongodb\Collection $collection) {
Jens Segers's avatar
Jens Segers committed
498
            return $collection->insertOne(['name' => 'Yvonne Yoe', 'age' => 35]);
Jens Segers's avatar
Jens Segers committed
499
        });
Jens Segers's avatar
Jens Segers committed
500
        $this->assertNotNull($result);
Jens Segers's avatar
Jens Segers committed
501 502
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
503
    public function testDotNotation(): void
Jens Segers's avatar
Jens Segers committed
504 505
    {
        $user = User::create([
Jens Segers's avatar
Jens Segers committed
506
            'name' => 'John Doe',
Jens Segers's avatar
Jens Segers committed
507
            'address' => [
Jens Segers's avatar
Jens Segers committed
508
                'city' => 'Paris',
Jens Segers's avatar
Jens Segers committed
509 510 511 512 513 514 515
                'country' => 'France',
            ],
        ]);

        $this->assertEquals('Paris', $user->getAttribute('address.city'));
        $this->assertEquals('Paris', $user['address.city']);
        $this->assertEquals('Paris', $user->{'address.city'});
516 517 518 519 520 521 522

        // Fill
        $user->fill([
            'address.city' => 'Strasbourg',
        ]);

        $this->assertEquals('Strasbourg', $user['address.city']);
Jens Segers's avatar
Jens Segers committed
523
    }
524

Simon Schaufelberger's avatar
Simon Schaufelberger committed
525
    public function testMultipleLevelDotNotation(): void
526
    {
Simon Schaufelberger's avatar
Simon Schaufelberger committed
527
        /** @var Book $book */
528 529 530 531 532 533 534 535 536 537 538 539 540 541
        $book = Book::create([
            'title' => 'A Game of Thrones',
            'chapters' => [
                'one' => [
                    'title' => 'The first chapter',
                ],
            ],
        ]);

        $this->assertEquals(['one' => ['title' => 'The first chapter']], $book->chapters);
        $this->assertEquals(['title' => 'The first chapter'], $book['chapters.one']);
        $this->assertEquals('The first chapter', $book['chapters.one.title']);
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
542
    public function testGetDirtyDates(): void
543 544 545 546 547 548 549 550
    {
        $user = new User();
        $user->setRawAttributes(['name' => 'John Doe', 'birthday' => new DateTime('19 august 1989')], true);
        $this->assertEmpty($user->getDirty());

        $user->birthday = new DateTime('19 august 1989');
        $this->assertEmpty($user->getDirty());
    }
David Furnes's avatar
David Furnes committed
551

Simon Schaufelberger's avatar
Simon Schaufelberger committed
552
    public function testChunkById(): void
David Furnes's avatar
David Furnes committed
553
    {
Jens Segers's avatar
Jens Segers committed
554
        User::create(['name' => 'fork', 'tags' => ['sharp', 'pointy']]);
David Furnes's avatar
David Furnes committed
555 556 557 558
        User::create(['name' => 'spork', 'tags' => ['sharp', 'pointy', 'round', 'bowl']]);
        User::create(['name' => 'spoon', 'tags' => ['round', 'bowl']]);

        $count = 0;
Simon Schaufelberger's avatar
Simon Schaufelberger committed
559
        User::chunkById(2, function (\Illuminate\Database\Eloquent\Collection $items) use (&$count) {
David Furnes's avatar
David Furnes committed
560 561 562 563 564
            $count += count($items);
        });

        $this->assertEquals(3, $count);
    }
565
}