Skip to content

Commit 40797ac

Browse files
committed
test: 💍 Add HasMany::firstOrCreate() snapshot tests
1 parent beab92f commit 40797ac

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

tests/Database/DatabaseEloquentHasManyTest.php

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,116 @@ public function testCreateOrFirstMethodRetrievesExistingRecord()
413413
});
414414
}
415415

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+
416526
protected function getRelation()
417527
{
418528
$builder = m::mock(Builder::class);

0 commit comments

Comments
 (0)