Skip to content

Commit 877e32f

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

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

tests/Database/DatabaseEloquentHasManyTest.php

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,117 @@ 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+
'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+
416527
protected function getRelation()
417528
{
418529
$builder = m::mock(Builder::class);

0 commit comments

Comments
 (0)