@@ -413,6 +413,116 @@ public function testCreateOrFirstMethodRetrievesExistingRecord()
413
413
});
414
414
}
415
415
416
+ public function testFirstOrCreateMethodCreatesNewRecord ()
417
+ {
418
+ Carbon::setTestNow ('2023-01-01 00:00:00 ' );
419
+
420
+ Model::unguarded (function () {
421
+ $ model = new EloquentHasManyModelStubWithRelation ();
422
+ $ model ->id = '123 ' ;
423
+ $ this ->mockConnectionForModel ($ model , 'SQLite ' );
424
+ $ model ->getConnection ()->shouldReceive ('transactionLevel ' )->andReturn (0 );
425
+ $ model ->getConnection ()->shouldReceive ('getName ' )->andReturn ('sqlite ' );
426
+
427
+ $ model ->getConnection ()
428
+ ->expects ('select ' )
429
+ ->with ('select * from "child_table" where "child_table"."foreign_key" = ? and "child_table"."foreign_key" is not null and ("attr" = ?) limit 1 ' , ['123 ' , 'foo ' ], true )
430
+ ->andReturn ([]);
431
+
432
+ $ model ->getConnection ()->expects ('insert ' )->with (
433
+ 'insert into "child_table" ("attr", "val", "foreign_key", "updated_at", "created_at") values (?, ?, ?, ?, ?) ' ,
434
+ ['foo ' , 'bar ' , '123 ' , '2023-01-01 00:00:00 ' , '2023-01-01 00:00:00 ' ],
435
+ )->andReturnTrue ();
436
+
437
+ $ result = $ model ->child ()->firstOrCreate (['attr ' => 'foo ' ], ['val ' => 'bar ' ]);
438
+ $ this ->assertEquals ([
439
+ 'foreign_key ' => '123 ' ,
440
+ 'attr ' => 'foo ' ,
441
+ 'val ' => 'bar ' ,
442
+ 'created_at ' => '2023-01-01T00:00:00.000000Z ' ,
443
+ 'updated_at ' => '2023-01-01T00:00:00.000000Z ' ,
444
+ ], $ result ->toArray ());
445
+ });
446
+ }
447
+
448
+ public function testFirstOrCreateMethodRetrievesExistingRecord ()
449
+ {
450
+ Carbon::setTestNow ('2023-01-01 00:00:00 ' );
451
+
452
+ Model::unguarded (function () {
453
+ $ model = new EloquentHasManyModelStubWithRelation ();
454
+ $ model ->id = '123 ' ;
455
+ $ this ->mockConnectionForModel ($ model , 'SQLite ' );
456
+ $ model ->getConnection ()->shouldReceive ('transactionLevel ' )->andReturn (0 );
457
+ $ model ->getConnection ()->shouldReceive ('getName ' )->andReturn ('sqlite ' );
458
+
459
+ $ model ->getConnection ()
460
+ ->expects ('select ' )
461
+ ->with ('select * from "child_table" where "child_table"."foreign_key" = ? and "child_table"."foreign_key" is not null and ("attr" = ?) limit 1 ' , ['123 ' , 'foo ' ], true )
462
+ ->andReturn ([]);
463
+
464
+ $ model ->getConnection ()->expects ('insert ' )->with (
465
+ 'insert into "child_table" ("attr", "val", "foreign_key", "updated_at", "created_at") values (?, ?, ?, ?, ?) ' ,
466
+ ['foo ' , 'bar ' , '123 ' , '2023-01-01 00:00:00 ' , '2023-01-01 00:00:00 ' ],
467
+ )->andReturnTrue ();
468
+
469
+ $ result = $ model ->child ()->firstOrCreate (['attr ' => 'foo ' ], ['val ' => 'bar ' ]);
470
+ $ this ->assertEquals ([
471
+ 'foreign_key ' => '123 ' ,
472
+ 'attr ' => 'foo ' ,
473
+ 'val ' => 'bar ' ,
474
+ 'created_at ' => '2023-01-01T00:00:00.000000Z ' ,
475
+ 'updated_at ' => '2023-01-01T00:00:00.000000Z ' ,
476
+ ], $ result ->toArray ());
477
+ });
478
+ }
479
+
480
+ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow ()
481
+ {
482
+ Carbon::setTestNow ('2023-01-01 00:00:00 ' );
483
+
484
+ Model::unguarded (function () {
485
+ $ model = new EloquentHasManyModelStubWithRelation ();
486
+ $ model ->id = '123 ' ;
487
+ $ this ->mockConnectionForModel ($ model , 'SQLite ' );
488
+ $ model ->getConnection ()->shouldReceive ('transactionLevel ' )->andReturn (0 );
489
+ $ model ->getConnection ()->shouldReceive ('getName ' )->andReturn ('sqlite ' );
490
+
491
+ $ model ->getConnection ()
492
+ ->expects ('select ' )
493
+ ->with ('select * from "child_table" where "child_table"."foreign_key" = ? and "child_table"."foreign_key" is not null and ("attr" = ?) limit 1 ' , ['123 ' , 'foo ' ], true )
494
+ ->andReturn ([]);
495
+
496
+ $ sql = 'insert into "child_table" ("attr", "val", "foreign_key", "updated_at", "created_at") values (?, ?, ?, ?, ?) ' ;
497
+ $ bindings = ['foo ' , 'bar ' , '123 ' , '2023-01-01 00:00:00 ' , '2023-01-01 00:00:00 ' ];
498
+
499
+ $ model ->getConnection ()
500
+ ->expects ('insert ' )
501
+ ->with ($ sql , $ bindings )
502
+ ->andThrow (new UniqueConstraintViolationException ('sqlite ' , $ sql , $ bindings , new Exception ()));
503
+
504
+ $ model ->getConnection ()
505
+ ->expects ('select ' )
506
+ ->with ('select * from "child_table" where "child_table"."foreign_key" = ? and "child_table"."foreign_key" is not null and ("attr" = ?) and ("attr" = ?) limit 1 ' , ['123 ' , 'foo ' , 'foo ' ], false )
507
+ ->andReturn ([[
508
+ 'foreign_key ' => '123 ' ,
509
+ 'attr ' => 'foo ' ,
510
+ 'val ' => 'bar ' ,
511
+ 'created_at ' => '2023-01-01 00:00:00 ' ,
512
+ 'updated_at ' => '2023-01-01 00:00:00 ' ,
513
+ ]]);
514
+
515
+ $ result = $ model ->child ()->firstOrCreate (['attr ' => 'foo ' ], ['val ' => 'bar ' ]);
516
+ $ this ->assertEquals ([
517
+ 'foreign_key ' => '123 ' ,
518
+ 'attr ' => 'foo ' ,
519
+ 'val ' => 'bar ' ,
520
+ 'created_at ' => '2023-01-01T00:00:00.000000Z ' ,
521
+ 'updated_at ' => '2023-01-01T00:00:00.000000Z ' ,
522
+ ], $ result ->toArray ());
523
+ });
524
+ }
525
+
416
526
protected function getRelation ()
417
527
{
418
528
$ builder = m::mock (Builder::class);
0 commit comments