Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Debugging] introduced test case that shows join reaction counter breaks when run with count on morphables #260

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
<env name="QUEUE_DRIVER" value="sync"/>
<env name="DB_CONNECTION" value="testing"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="DB_CONNECTION" value="mysql"/>
<env name="DB_DATABASE" value="love-test-database"/>
<env name="DB_PASSWORD" value="password"/>
<server name="APP_ENV" value="testing"/>
<server name="CACHE_DRIVER" value="array"/>
<server name="SESSION_DRIVER" value="array"/>
<server name="QUEUE_DRIVER" value="sync"/>
<server name="DB_CONNECTION" value="testing"/>
<server name="DB_DATABASE" value=":memory:"/>
<env name="DB_CONNECTION" value="mysql"/>
<env name="DB_DATABASE" value="love-test-database"/>
<env name="DB_PASSWORD" value="password"/>
</php>
</phpunit>
6 changes: 6 additions & 0 deletions tests/Stubs/Models/Article.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
use Cog\Laravel\Love\Reactable\Models\Traits\Reactable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphMany;

/**
* @method static ArticleEloquentBuilder query()
Expand Down Expand Up @@ -48,4 +49,9 @@ public function newEloquentBuilder($query): ArticleEloquentBuilder
{
return new ArticleEloquentBuilder($query);
}

public function morphableEntities(): MorphMany
{
return $this->morphMany(MorphableEntity::class, 'morphable');
}
}
42 changes: 42 additions & 0 deletions tests/Stubs/Models/MorphableEntity.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

/*
* This file is part of Laravel Love.
*
* (c) Anton Komarev <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Cog\Tests\Laravel\Love\Stubs\Models;

use Cog\Contracts\Love\Reactable\Models\Reactable as ReactableInterface;
use Cog\Laravel\Love\Reactable\Models\Traits\Reactable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

final class MorphableEntity extends Model implements
ReactableInterface
{
use HasFactory;
use Reactable;

/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'morphable_entities';

/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
];
}
78 changes: 78 additions & 0 deletions tests/Unit/Reactable/ReactableEloquentBuilderTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
use Cog\Laravel\Love\Reaction\Models\Reaction;
use Cog\Laravel\Love\ReactionType\Models\ReactionType;
use Cog\Tests\Laravel\Love\Stubs\Models\Article;
use Cog\Tests\Laravel\Love\Stubs\Models\Entity;
use Cog\Tests\Laravel\Love\Stubs\Models\MorphableEntity;
use Cog\Tests\Laravel\Love\Stubs\Models\User;
use Cog\Tests\Laravel\Love\TestCase;
use Illuminate\Support\Str;
Expand Down Expand Up @@ -1140,4 +1142,80 @@ public function it_can_chain_multiple_join_reaction_counter_of_type_with_custom_
];
})->toArray());
}

/** @test */
public function it_breaks_when_join_reaction_counter_with_type_is_used_with_count_on_morphables(): void
{
Reactant::factory()->create(); // Needed to have not same ids with Reactant

$reactionType1 = ReactionType::factory()->create([
'name' => 'Like',
'mass' => 2,
]);
$reactionType2 = ReactionType::factory()->create([
'mass' => 1,
]);
$reactable1 = Article::factory()->has(MorphableEntity::factory()->count(3))->create();
$reactable2 = Article::factory()->has(MorphableEntity::factory()->count(2))->create();
$reactable3 = Article::factory()->has(MorphableEntity::factory()->count(4))->create();
Reaction::factory()->count(2)->create([
'reaction_type_id' => $reactionType1->getId(),
'reactant_id' => $reactable1->getLoveReactant()->getId(),
]);
Reaction::factory()->count(3)->create([
'reaction_type_id' => $reactionType1->getId(),
'reactant_id' => $reactable2->getLoveReactant()->getId(),
]);
Reaction::factory()->count(1)->create([
'reaction_type_id' => $reactionType1->getId(),
'reactant_id' => $reactable3->getLoveReactant()->getId(),
]);
Reaction::factory()->count(4)->create([
'reaction_type_id' => $reactionType2->getId(),
'reactant_id' => $reactable1->getLoveReactant()->getId(),
]);
Reaction::factory()->count(5)->create([
'reaction_type_id' => $reactionType2->getId(),
'reactant_id' => $reactable2->getLoveReactant()->getId(),
]);
Reaction::factory()->count(6)->create([
'reaction_type_id' => $reactionType2->getId(),
'reactant_id' => $reactable3->getLoveReactant()->getId(),
]);

$reactionType1CountKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_count';
$reactionType1WeightKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_weight';

$reactablesOrderedAsc = Article::query()
->withCount(['morphableEntities'])
->joinReactionCounterOfType($reactionType1->getName())
->orderBy($reactionType1CountKey, 'asc')
->get();

$reactablesOrderedDesc = Article::query()
->joinReactionCounterOfType($reactionType1->getName())
->orderBy($reactionType1CountKey, 'desc')
->get();

$assertAsc = [
['name' => $reactable3->name, "$reactionType1CountKey" => 1, "$reactionType1WeightKey" => 2],
['name' => $reactable1->name, "$reactionType1CountKey" => 2, "$reactionType1WeightKey" => 4],
['name' => $reactable2->name, "$reactionType1CountKey" => 3, "$reactionType1WeightKey" => 6],
];
$assertDesc = array_reverse($assertAsc);
$this->assertEquals($assertAsc, $reactablesOrderedAsc->map(function (Article $reactable) use ($reactionType1CountKey, $reactionType1WeightKey) {
return [
'name' => $reactable->getAttributeValue('name'),
"$reactionType1CountKey" => $reactable->{$reactionType1CountKey},
"$reactionType1WeightKey" => $reactable->{$reactionType1WeightKey},
];
})->toArray());
$this->assertEquals($assertDesc, $reactablesOrderedDesc->map(function (Article $reactable) use ($reactionType1CountKey, $reactionType1WeightKey) {
return [
'name' => $reactable->getAttributeValue('name'),
"$reactionType1CountKey" => $reactable->{$reactionType1CountKey},
"$reactionType1WeightKey" => $reactable->{$reactionType1WeightKey},
];
})->toArray());
}
}
34 changes: 34 additions & 0 deletions tests/database/factories/MorphableEntityFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

/*
* This file is part of Laravel Ban.
*
* (c) Anton Komarev <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Cog\Tests\Laravel\Love\Database\Factories;

use Cog\Tests\Laravel\Love\Stubs\Models\MorphableEntity;
use Illuminate\Database\Eloquent\Factories\Factory;

final class MorphableEntityFactory extends Factory
{
protected $model = MorphableEntity::class;

/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'name' => $this->faker->name(),
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

/*
* This file is part of Laravel Love.
*
* (c) Anton Komarev <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
public function up(): void
{
Schema::create('morphable_entities', function (Blueprint $table) {
$table->increments('id');
$table->morphs('morphable');
$table->unsignedBigInteger('love_reactant_id')->nullable();
$table->string('name');
$table->timestamps();
});
}

public function down(): void
{
Schema::dropIfExists('morphable_entities');
}
};
Loading