1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
|
<?php
namespace Illuminate\Tests\Database;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
use Mockery as m;
use PHPUnit\Framework\TestCase;
use stdClass;
class DatabaseEloquentMorphToManyTest extends TestCase
{
protected function tearDown(): void
{
m::close();
}
public function testEagerConstraintsAreProperlyAdded()
{
$relation = $this->getRelation();
$relation->getParent()->shouldReceive('getKeyName')->andReturn('id');
$relation->getParent()->shouldReceive('getKeyType')->once()->andReturn('int');
$relation->getQuery()->shouldReceive('whereIntegerInRaw')->once()->with('taggables.taggable_id', [1, 2]);
$relation->getQuery()->shouldReceive('where')->once()->with('taggables.taggable_type', get_class($relation->getParent()));
$model1 = new EloquentMorphToManyModelStub;
$model1->id = 1;
$model2 = new EloquentMorphToManyModelStub;
$model2->id = 2;
$relation->addEagerConstraints([$model1, $model2]);
}
public function testAttachInsertsPivotTableRecord()
{
$relation = $this->getMockBuilder(MorphToMany::class)->onlyMethods(['touchIfTouching'])->setConstructorArgs($this->getRelationArguments())->getMock();
$query = m::mock(stdClass::class);
$query->shouldReceive('from')->once()->with('taggables')->andReturn($query);
$query->shouldReceive('insert')->once()->with([['taggable_id' => 1, 'taggable_type' => get_class($relation->getParent()), 'tag_id' => 2, 'foo' => 'bar']])->andReturn(true);
$relation->getQuery()->shouldReceive('getQuery')->andReturn($mockQueryBuilder = m::mock(stdClass::class));
$mockQueryBuilder->shouldReceive('newQuery')->once()->andReturn($query);
$relation->expects($this->once())->method('touchIfTouching');
$relation->attach(2, ['foo' => 'bar']);
}
public function testDetachRemovesPivotTableRecord()
{
$relation = $this->getMockBuilder(MorphToMany::class)->onlyMethods(['touchIfTouching'])->setConstructorArgs($this->getRelationArguments())->getMock();
$query = m::mock(stdClass::class);
$query->shouldReceive('from')->once()->with('taggables')->andReturn($query);
$query->shouldReceive('where')->once()->with('taggables.taggable_id', 1)->andReturn($query);
$query->shouldReceive('where')->once()->with('taggable_type', get_class($relation->getParent()))->andReturn($query);
$query->shouldReceive('whereIn')->once()->with('taggables.tag_id', [1, 2, 3]);
$query->shouldReceive('delete')->once()->andReturn(true);
$relation->getQuery()->shouldReceive('getQuery')->andReturn($mockQueryBuilder = m::mock(stdClass::class));
$mockQueryBuilder->shouldReceive('newQuery')->once()->andReturn($query);
$relation->expects($this->once())->method('touchIfTouching');
$this->assertTrue($relation->detach([1, 2, 3]));
}
public function testDetachMethodClearsAllPivotRecordsWhenNoIDsAreGiven()
{
$relation = $this->getMockBuilder(MorphToMany::class)->onlyMethods(['touchIfTouching'])->setConstructorArgs($this->getRelationArguments())->getMock();
$query = m::mock(stdClass::class);
$query->shouldReceive('from')->once()->with('taggables')->andReturn($query);
$query->shouldReceive('where')->once()->with('taggables.taggable_id', 1)->andReturn($query);
$query->shouldReceive('where')->once()->with('taggable_type', get_class($relation->getParent()))->andReturn($query);
$query->shouldReceive('whereIn')->never();
$query->shouldReceive('delete')->once()->andReturn(true);
$relation->getQuery()->shouldReceive('getQuery')->andReturn($mockQueryBuilder = m::mock(stdClass::class));
$mockQueryBuilder->shouldReceive('newQuery')->once()->andReturn($query);
$relation->expects($this->once())->method('touchIfTouching');
$this->assertTrue($relation->detach());
}
public function getRelation()
{
[$builder, $parent] = $this->getRelationArguments();
return new MorphToMany($builder, $parent, 'taggable', 'taggables', 'taggable_id', 'tag_id', 'id', 'id');
}
public function getRelationArguments()
{
$parent = m::mock(Model::class);
$parent->shouldReceive('getMorphClass')->andReturn(get_class($parent));
$parent->shouldReceive('getKey')->andReturn(1);
$parent->shouldReceive('getCreatedAtColumn')->andReturn('created_at');
$parent->shouldReceive('getUpdatedAtColumn')->andReturn('updated_at');
$parent->shouldReceive('getMorphClass')->andReturn(get_class($parent));
$parent->shouldReceive('getAttribute')->with('id')->andReturn(1);
$builder = m::mock(Builder::class);
$related = m::mock(Model::class);
$builder->shouldReceive('getModel')->andReturn($related);
$related->shouldReceive('getTable')->andReturn('tags');
$related->shouldReceive('getKeyName')->andReturn('id');
$related->shouldReceive('qualifyColumn')->with('id')->andReturn('tags.id');
$related->shouldReceive('getMorphClass')->andReturn(get_class($related));
$builder->shouldReceive('join')->once()->with('taggables', 'tags.id', '=', 'taggables.tag_id');
$builder->shouldReceive('where')->once()->with('taggables.taggable_id', '=', 1);
$builder->shouldReceive('where')->once()->with('taggables.taggable_type', get_class($parent));
return [$builder, $parent, 'taggable', 'taggables', 'taggable_id', 'tag_id', 'id', 'id', 'relation_name', false];
}
}
class EloquentMorphToManyModelStub extends Model
{
protected $guarded = [];
}
|