Skip to content

Commit

Permalink
introduced test case that shows join reaction counter breaks when run…
Browse files Browse the repository at this point in the history
… with count on morphables
  • Loading branch information
jfunulab committed Oct 1, 2024
1 parent 263a666 commit 473e80f
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 4 deletions.
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');
}
};

0 comments on commit 473e80f

Please sign in to comment.