@@ -413,6 +413,117 @@ 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
+ 'foreign_key ' => '123 ' ,
464
+ 'attr ' => 'foo ' ,
465
+ 'val ' => 'bar ' ,
466
+ 'created_at ' => '2023-01-01T00:00:00.000000Z ' ,
467
+ 'updated_at ' => '2023-01-01T00:00:00.000000Z ' ,
468
+ ]]);
469
+
470
+ $ result = $ model ->child ()->firstOrCreate (['attr ' => 'foo ' ], ['val ' => 'bar ' ]);
471
+ $ this ->assertEquals ([
472
+ 'foreign_key ' => '123 ' ,
473
+ 'attr ' => 'foo ' ,
474
+ 'val ' => 'bar ' ,
475
+ 'created_at ' => '2023-01-01T00:00:00.000000Z ' ,
476
+ 'updated_at ' => '2023-01-01T00:00:00.000000Z ' ,
477
+ ], $ result ->toArray ());
478
+ });
479
+ }
480
+
481
+ public function testFirstOrCreateMethodRetrievesRecordCreatedJustNow ()
482
+ {
483
+ Carbon::setTestNow ('2023-01-01 00:00:00 ' );
484
+
485
+ Model::unguarded (function () {
486
+ $ model = new EloquentHasManyModelStubWithRelation ();
487
+ $ model ->id = '123 ' ;
488
+ $ this ->mockConnectionForModel ($ model , 'SQLite ' );
489
+ $ model ->getConnection ()->shouldReceive ('transactionLevel ' )->andReturn (0 );
490
+ $ model ->getConnection ()->shouldReceive ('getName ' )->andReturn ('sqlite ' );
491
+
492
+ $ model ->getConnection ()
493
+ ->expects ('select ' )
494
+ ->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 )
495
+ ->andReturn ([]);
496
+
497
+ $ sql = 'insert into "child_table" ("attr", "val", "foreign_key", "updated_at", "created_at") values (?, ?, ?, ?, ?) ' ;
498
+ $ bindings = ['foo ' , 'bar ' , '123 ' , '2023-01-01 00:00:00 ' , '2023-01-01 00:00:00 ' ];
499
+
500
+ $ model ->getConnection ()
501
+ ->expects ('insert ' )
502
+ ->with ($ sql , $ bindings )
503
+ ->andThrow (new UniqueConstraintViolationException ('sqlite ' , $ sql , $ bindings , new Exception ()));
504
+
505
+ $ model ->getConnection ()
506
+ ->expects ('select ' )
507
+ ->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 )
508
+ ->andReturn ([[
509
+ 'foreign_key ' => '123 ' ,
510
+ 'attr ' => 'foo ' ,
511
+ 'val ' => 'bar ' ,
512
+ 'created_at ' => '2023-01-01 00:00:00 ' ,
513
+ 'updated_at ' => '2023-01-01 00:00:00 ' ,
514
+ ]]);
515
+
516
+ $ result = $ model ->child ()->firstOrCreate (['attr ' => 'foo ' ], ['val ' => 'bar ' ]);
517
+ $ this ->assertEquals ([
518
+ 'foreign_key ' => '123 ' ,
519
+ 'attr ' => 'foo ' ,
520
+ 'val ' => 'bar ' ,
521
+ 'created_at ' => '2023-01-01T00:00:00.000000Z ' ,
522
+ 'updated_at ' => '2023-01-01T00:00:00.000000Z ' ,
523
+ ], $ result ->toArray ());
524
+ });
525
+ }
526
+
416
527
protected function getRelation ()
417
528
{
418
529
$ builder = m::mock (Builder::class);
0 commit comments