ModelTest.php 17.9 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
use Carbon\Carbon;
5
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
Simon Schaufelberger's avatar
Simon Schaufelberger committed
6
use Illuminate\Database\Eloquent\ModelNotFoundException;
7 8
use Jenssegers\Mongodb\Collection;
use Jenssegers\Mongodb\Connection;
Jens Segers's avatar
Jens Segers committed
9 10 11 12
use Jenssegers\Mongodb\Eloquent\Model;
use MongoDB\BSON\ObjectID;
use MongoDB\BSON\UTCDateTime;

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

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

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

        $user->save();

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

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

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

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

Simon Schaufelberger's avatar
Simon Schaufelberger committed
58
    public function testUpdate(): void
Jens Segers's avatar
Jens Segers committed
59 60 61 62 63 64 65 66
    {
        $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
67
        $this->assertInstanceOf(ObjectID::class, $raw['_id']);
Jens Segers's avatar
Jens Segers committed
68

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

Gabriel Caruso's avatar
Gabriel Caruso committed
74
        $this->assertTrue($check->exists);
Jens Segers's avatar
Jens Segers committed
75 76
        $this->assertInstanceOf(Carbon::class, $check->created_at);
        $this->assertInstanceOf(Carbon::class, $check->updated_at);
Jens Segers's avatar
Jens Segers committed
77 78 79 80 81 82 83 84
        $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
85
        $this->assertInstanceOf(ObjectID::class, $raw['_id']);
Jens Segers's avatar
Jens Segers committed
86 87 88 89 90

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

Simon Schaufelberger's avatar
Simon Schaufelberger committed
91
    public function testManualStringId(): void
Jens Segers's avatar
Jens Segers committed
92 93 94 95 96 97 98 99
    {
        $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
100
        $this->assertTrue($user->exists);
Jens Segers's avatar
Jens Segers committed
101 102 103
        $this->assertEquals('4af9f23d8ead0e1d32000000', $user->_id);

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

        $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
113
        $this->assertTrue($user->exists);
Jens Segers's avatar
Jens Segers committed
114 115 116
        $this->assertEquals('customId', $user->_id);

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

Simon Schaufelberger's avatar
Simon Schaufelberger committed
120
    public function testManualIntId(): void
Jens Segers's avatar
Jens Segers committed
121 122 123 124 125 126 127 128
    {
        $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
129
        $this->assertTrue($user->exists);
Jens Segers's avatar
Jens Segers committed
130 131 132
        $this->assertEquals(1, $user->_id);

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

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

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

        $user->delete();

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

Simon Schaufelberger's avatar
Simon Schaufelberger committed
152
    public function testAll(): void
Jens Segers's avatar
Jens Segers committed
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
    {
        $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
168
        $this->assertCount(2, $all);
Pooya Parsa's avatar
Pooya Parsa committed
169 170
        $this->assertContains('John Doe', $all->pluck('name'));
        $this->assertContains('Jane Doe', $all->pluck('name'));
Jens Segers's avatar
Jens Segers committed
171 172
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Simon Schaufelberger's avatar
Simon Schaufelberger committed
251
    public function testDestroy(): void
Jens Segers's avatar
Jens Segers committed
252 253 254 255 256 257 258 259 260 261 262 263
    {
        $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
264
    public function testTouch(): void
Jens Segers's avatar
Jens Segers committed
265 266 267 268 269 270 271 272 273 274
    {
        $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
275 276

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

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

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

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

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

        $user->delete();
Gabriel Caruso's avatar
Gabriel Caruso committed
296
        $this->assertTrue($user->trashed());
Jens Segers's avatar
Jens Segers committed
297 298 299 300 301 302 303 304 305 306
        $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
307
        $this->assertInstanceOf(Carbon::class, $user->deleted_at);
Gabriel Caruso's avatar
Gabriel Caruso committed
308
        $this->assertTrue($user->trashed());
Jens Segers's avatar
Jens Segers committed
309 310 311 312 313

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

Simon Schaufelberger's avatar
Simon Schaufelberger committed
314
    public function testPrimaryKey(): void
Jens Segers's avatar
Jens Segers committed
315 316 317 318 319 320 321 322 323 324 325 326 327
    {
        $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
328
        /** @var Book $check */
Jens Segers's avatar
Jens Segers committed
329 330 331 332 333 334
        $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
335
    public function testScope(): void
Jens Segers's avatar
Jens Segers committed
336 337 338 339 340 341 342 343 344 345
    {
        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
346
    public function testToArray(): void
Jens Segers's avatar
Jens Segers committed
347 348 349 350
    {
        $item = Item::create(['name' => 'fork', 'type' => 'sharp']);

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

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

        $user1->unset('note1');

366
        $this->assertFalse(isset($user1->note1));
Jens Segers's avatar
Jens Segers committed
367 368 369 370 371 372 373 374
        $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);

375
        $this->assertFalse(isset($user1->note1));
Jens Segers's avatar
Jens Segers committed
376 377 378 379 380 381
        $this->assertTrue(isset($user1->note2));
        $this->assertTrue(isset($user2->note1));
        $this->assertTrue(isset($user2->note2));

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

382 383
        $this->assertFalse(isset($user2->note1));
        $this->assertFalse(isset($user2->note2));
Jens Segers's avatar
Jens Segers committed
384 385
    }

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

        $check = User::find($user->_id);
Jens Segers's avatar
Jens Segers committed
393
        $this->assertInstanceOf(Carbon::class, $check->birthday);
Jens Segers's avatar
Jens Segers committed
394 395 396 397 398 399 400
        $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();
401 402
        $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
403

Jens Segers's avatar
Jens Segers committed
404 405 406 407 408 409
        // 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
410
        $this->assertLessThan(2, abs(time() - $item->created_at->getTimestamp()));
Jens Segers's avatar
Jens Segers committed
411

Jens Segers's avatar
Jens Segers committed
412
        // test default date format for json output
Simon Schaufelberger's avatar
Simon Schaufelberger committed
413
        /** @var Item $item */
Jens Segers's avatar
Jens Segers committed
414 415 416 417
        $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
418
        /** @var User $user */
Jens Segers's avatar
Jens Segers committed
419
        $user = User::create(['name' => 'Jane Doe', 'birthday' => time()]);
Jens Segers's avatar
Jens Segers committed
420
        $this->assertInstanceOf(Carbon::class, $user->birthday);
Jens Segers's avatar
Jens Segers committed
421 422

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

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

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

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

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

439 440
    public function testCarbonDateMockingWorks()
    {
441
        $fakeDate = Carbon::createFromDate(2000, 01, 01);
442 443 444

        Carbon::setTestNow($fakeDate);
        $item = Item::create(['name' => 'sword']);
445

Manan Jadhav's avatar
Manan Jadhav committed
446
        $this->assertLessThan(1, $fakeDate->diffInSeconds($item->created_at));
447 448
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
449
    public function testIdAttribute(): void
Jens Segers's avatar
Jens Segers committed
450
    {
Simon Schaufelberger's avatar
Simon Schaufelberger committed
451
        /** @var User $user */
Jens Segers's avatar
Jens Segers committed
452 453 454 455 456 457 458
        $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
459
    public function testPushPull(): void
Jens Segers's avatar
Jens Segers committed
460
    {
Simon Schaufelberger's avatar
Simon Schaufelberger committed
461
        /** @var User $user */
Jens Segers's avatar
Jens Segers committed
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485
        $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
486
    public function testRaw(): void
Jens Segers's avatar
Jens Segers committed
487 488 489 490 491
    {
        User::create(['name' => 'John Doe', 'age' => 35]);
        User::create(['name' => 'Jane Doe', 'age' => 35]);
        User::create(['name' => 'Harry Hoe', 'age' => 15]);

492
        $users = User::raw(function (Collection $collection) {
Jens Segers's avatar
Jens Segers committed
493 494
            return $collection->find(['age' => 35]);
        });
Ditty's avatar
Ditty committed
495
        $this->assertInstanceOf(EloquentCollection::class, $users);
Jens Segers's avatar
Jens Segers committed
496
        $this->assertInstanceOf(Model::class, $users[0]);
Jens Segers's avatar
Jens Segers committed
497

498
        $user = User::raw(function (Collection $collection) {
Jens Segers's avatar
Jens Segers committed
499 500
            return $collection->findOne(['age' => 35]);
        });
501

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

504
        $count = User::raw(function (Collection $collection) {
Jens Segers's avatar
Jens Segers committed
505 506 507 508
            return $collection->count();
        });
        $this->assertEquals(3, $count);

509
        $result = User::raw(function (Collection $collection) {
Jens Segers's avatar
Jens Segers committed
510
            return $collection->insertOne(['name' => 'Yvonne Yoe', 'age' => 35]);
Jens Segers's avatar
Jens Segers committed
511
        });
Jens Segers's avatar
Jens Segers committed
512
        $this->assertNotNull($result);
Jens Segers's avatar
Jens Segers committed
513 514
    }

Simon Schaufelberger's avatar
Simon Schaufelberger committed
515
    public function testDotNotation(): void
Jens Segers's avatar
Jens Segers committed
516 517
    {
        $user = User::create([
Jens Segers's avatar
Jens Segers committed
518
            'name' => 'John Doe',
Jens Segers's avatar
Jens Segers committed
519
            'address' => [
Jens Segers's avatar
Jens Segers committed
520
                'city' => 'Paris',
Jens Segers's avatar
Jens Segers committed
521 522 523 524 525 526 527
                'country' => 'France',
            ],
        ]);

        $this->assertEquals('Paris', $user->getAttribute('address.city'));
        $this->assertEquals('Paris', $user['address.city']);
        $this->assertEquals('Paris', $user->{'address.city'});
528 529 530 531 532 533 534

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

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

Simon Schaufelberger's avatar
Simon Schaufelberger committed
537
    public function testMultipleLevelDotNotation(): void
538
    {
Simon Schaufelberger's avatar
Simon Schaufelberger committed
539
        /** @var Book $book */
540 541 542 543 544 545 546 547 548 549 550 551 552 553
        $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
554
    public function testGetDirtyDates(): void
555 556 557 558 559 560 561 562
    {
        $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
563

Simon Schaufelberger's avatar
Simon Schaufelberger committed
564
    public function testChunkById(): void
David Furnes's avatar
David Furnes committed
565
    {
Jens Segers's avatar
Jens Segers committed
566
        User::create(['name' => 'fork', 'tags' => ['sharp', 'pointy']]);
David Furnes's avatar
David Furnes committed
567 568 569 570
        User::create(['name' => 'spork', 'tags' => ['sharp', 'pointy', 'round', 'bowl']]);
        User::create(['name' => 'spoon', 'tags' => ['round', 'bowl']]);

        $count = 0;
571
        User::chunkById(2, function (EloquentCollection $items) use (&$count) {
David Furnes's avatar
David Furnes committed
572 573 574 575 576
            $count += count($items);
        });

        $this->assertEquals(3, $count);
    }
Ditty's avatar
Ditty committed
577 578 579 580 581 582 583 584 585

    public function testTruncateModel()
    {
        User::create(['name' => 'John Doe']);

        User::truncate();

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