From 46efb58e4575e9b3dcb6d455de1fed8e5a3c801a Mon Sep 17 00:00:00 2001 From: Anton Komarev Date: Fri, 6 Jan 2023 19:00:08 +0300 Subject: [PATCH 1/3] Extract local Model scopes to Eloquent Builder traits --- CHANGELOG.md | 10 +- UPGRADING.md | 31 + src/Reactable/Models/Traits/Reactable.php | 81 -- .../ReactableEloquentBuilderTrait.php | 133 ++ src/Reacterable/Models/Traits/Reacterable.php | 35 - .../ReacterableEloquentBuilderTrait.php | 110 ++ tests/Stubs/Models/Article.php | 9 + tests/Stubs/Models/ArticleEloquentBuilder.php | 22 + tests/Stubs/Models/User.php | 9 + tests/Stubs/Models/UserEloquentBuilder.php | 24 + .../Reactable/Models/Traits/ReactableTest.php | 1122 ---------------- .../ReactableEloquentBuilderTraitTest.php | 1143 +++++++++++++++++ .../Models/Traits/ReacterableTest.php | 240 ---- .../ReacterableEloquentBuilderTraitTest.php | 311 +++++ 14 files changed, 1800 insertions(+), 1480 deletions(-) create mode 100644 src/Reactable/ReactableEloquentBuilderTrait.php create mode 100644 src/Reacterable/ReacterableEloquentBuilderTrait.php create mode 100644 tests/Stubs/Models/ArticleEloquentBuilder.php create mode 100644 tests/Stubs/Models/UserEloquentBuilder.php create mode 100644 tests/Unit/Reactable/ReactableEloquentBuilderTraitTest.php create mode 100644 tests/Unit/Reacterable/ReacterableEloquentBuilderTraitTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 92ab4683..4a5c35d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,15 +4,20 @@ All notable changes to `laravel-love` will be documented in this file. ## [Unreleased] +Code has breaking changes because of Eloquent Model local scopes refactoring. + +Follow [upgrade instructions](UPGRADING.md#from-v8-to-v9) to migrate code. + ### Added - ([#234]) Added Laravel 10 support - ([#216]) Added Docker Compose to quick development build -- ([#188]) Added `whereReactedTo` model scope to Reacterable models -- ([#188]) Added `whereNotReactedTo` model scope to Reacterable models +- ([#227]) Added `whereReactedTo` model scope to Reacterable models +- ([#227]) Added `whereNotReactedTo` model scope to Reacterable models ### Changed +- ([#227]) Extracted Reactable model scopes to `ReactableEloquentBuilderTrait` - ([#231]) Console command `love:setup-reactable` generates migration with nullable column `love_reactant_id` by default - ([#231]) Console command `love:setup-reactable` option `--nullable` replaced with `--not-nullable` - ([#231]) Console command `love:setup-reacterable` generates migration with nullable column `love_reacter_id` by default @@ -572,6 +577,7 @@ Follow [upgrade instructions](UPGRADING.md#from-v5-to-v6) to migrate database to [#234]: https://github.com/cybercog/laravel-love/pull/234 [#233]: https://github.com/cybercog/laravel-love/pull/233 [#231]: https://github.com/cybercog/laravel-love/pull/231 +[#227]: https://github.com/cybercog/laravel-love/pull/227 [#222]: https://github.com/cybercog/laravel-love/pull/222 [#218]: https://github.com/cybercog/laravel-love/pull/218 [#217]: https://github.com/cybercog/laravel-love/pull/217 diff --git a/UPGRADING.md b/UPGRADING.md index d6038324..1fad5635 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -1,11 +1,42 @@ # Upgrade Guide +- [From v8 to v9](#from-v8-to-v9) - [From v7 to v8](#from-v7-to-v8) - [From v6 to v7](#from-v6-to-v7) - [From v5 to v6](#from-v5-to-v6) - [From v4 to v5](#from-v4-to-v5) - [From v3 to v4](#from-v3-to-v4) +## From v8 to v9 + +Release v9 has new Eloquent model local scopes approach described in ([#226](https://github.com/cybercog/laravel-love/discussions/226#discussioncomment-4612667)). + +Reactable trait methods `scopeWhereReactedBy`, `scopeWhereNotReactedBy`, `scopeJoinReactionCounterOfType`, `scopeJoinReactionTotal` +were moved to `ReactableEloquentBuilderTrait`. + +To start using them you have to create custom Eloquent Builder class, use trait in it and declare +that it should be used in your model as default query builder in `newEloquentBuilder` method: + +```php +/** + * @method static UserEloquentBuilder query() + */ +class User extends Model +{ + public function newEloquentBuilder($query): UserEloquentBuilder + { + return new UserEloquentBuilder($query); + } +} + +class UserEloquentBuilder extends \Illuminate\Database\Eloquent\Builder +{ + use \Cog\Laravel\Love\Reactable\ReactableEloquentBuilderTrait; + + // Other User model local query scopes +} +``` + ## From v7 to v8 - All `weight` values are `float` now. Round them to get `integer` values as it was before diff --git a/src/Reactable/Models/Traits/Reactable.php b/src/Reactable/Models/Traits/Reactable.php index 846db6de..c37d27e4 100644 --- a/src/Reactable/Models/Traits/Reactable.php +++ b/src/Reactable/Models/Traits/Reactable.php @@ -16,18 +16,11 @@ use Cog\Contracts\Love\Reactable\Exceptions\AlreadyRegisteredAsLoveReactant; use Cog\Contracts\Love\Reactant\Facades\Reactant as ReactantFacadeInterface; use Cog\Contracts\Love\Reactant\Models\Reactant as ReactantInterface; -use Cog\Contracts\Love\Reacterable\Models\Reacterable as ReacterableInterface; use Cog\Laravel\Love\Reactable\Observers\ReactableObserver; use Cog\Laravel\Love\Reactant\Facades\Reactant as ReactantFacade; use Cog\Laravel\Love\Reactant\Models\NullReactant; use Cog\Laravel\Love\Reactant\Models\Reactant; -use Cog\Laravel\Love\Reactant\ReactionCounter\Models\ReactionCounter; -use Cog\Laravel\Love\Reactant\ReactionTotal\Models\ReactionTotal; -use Cog\Laravel\Love\ReactionType\Models\ReactionType; -use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Relations\BelongsTo; -use Illuminate\Database\Query\JoinClause; -use Illuminate\Support\Str; /** * @mixin \Cog\Contracts\Love\Reactable\Models\Reactable @@ -78,78 +71,4 @@ public function registerAsLoveReactant(): void $this->setAttribute('love_reactant_id', $reactant->getId()); $this->save(); } - - public function scopeWhereReactedBy( - Builder $query, - ReacterableInterface $reacterable, - ?string $reactionTypeName = null, - ): Builder { - return $query->whereHas( - 'loveReactant.reactions', - function (Builder $reactionsQuery) use ($reacterable, $reactionTypeName) { - $reactionsQuery->where('reacter_id', $reacterable->getLoveReacter()->getId()); - if ($reactionTypeName !== null) { - $reactionsQuery->where('reaction_type_id', ReactionType::fromName($reactionTypeName)->getId()); - } - } - ); - } - - public function scopeWhereNotReactedBy( - Builder $query, - ReacterableInterface $reacterable, - ?string $reactionTypeName = null, - ): Builder { - return $query->whereDoesntHave( - 'loveReactant.reactions', - function (Builder $reactionsQuery) use ($reacterable, $reactionTypeName) { - $reactionsQuery->where('reacter_id', $reacterable->getLoveReacter()->getId()); - if ($reactionTypeName !== null) { - $reactionsQuery->where('reaction_type_id', ReactionType::fromName($reactionTypeName)->getId()); - } - } - ); - } - - public function scopeJoinReactionCounterOfType( - Builder $query, - string $reactionTypeName, - ?string $alias = null, - ): Builder { - $reactionType = ReactionType::fromName($reactionTypeName); - $alias = $alias === null ? 'reaction_' . Str::snake($reactionType->getName()) : $alias; - - $select = $query->getQuery()->columns ?? ["{$this->getTable()}.*"]; - $select[] = $query->raw("COALESCE({$alias}.count, 0) as {$alias}_count"); - $select[] = $query->raw("COALESCE({$alias}.weight, 0) as {$alias}_weight"); - - return $query - ->leftJoin( - (new ReactionCounter())->getTable() . ' as ' . $alias, - function (JoinClause $join) use ($reactionType, $alias) { - $join->on("{$alias}.reactant_id", '=', "{$this->getTable()}.love_reactant_id"); - $join->where("{$alias}.reaction_type_id", $reactionType->getId()); - } - ) - ->select($select); - } - - public function scopeJoinReactionTotal( - Builder $query, - ?string $alias = null, - ): Builder { - $alias = $alias === null ? 'reaction_total' : $alias; - $select = $query->getQuery()->columns ?? ["{$this->getTable()}.*"]; - $select[] = $query->raw("COALESCE({$alias}.count, 0) as {$alias}_count"); - $select[] = $query->raw("COALESCE({$alias}.weight, 0) as {$alias}_weight"); - - return $query - ->leftJoin( - (new ReactionTotal())->getTable() . ' as ' . $alias, - "{$alias}.reactant_id", - '=', - "{$this->getTable()}.love_reactant_id" - ) - ->select($select); - } } diff --git a/src/Reactable/ReactableEloquentBuilderTrait.php b/src/Reactable/ReactableEloquentBuilderTrait.php new file mode 100644 index 00000000..cafd1ee3 --- /dev/null +++ b/src/Reactable/ReactableEloquentBuilderTrait.php @@ -0,0 +1,133 @@ + + * + * 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\Laravel\Love\Reactable; + +use Cog\Contracts\Love\Reacterable\Models\Reacterable as ReacterableInterface; +use Cog\Laravel\Love\Reactant\ReactionCounter\Models\ReactionCounter; +use Cog\Laravel\Love\Reactant\ReactionTotal\Models\ReactionTotal; +use Cog\Laravel\Love\ReactionType\Models\ReactionType; +use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Query\JoinClause; +use Illuminate\Support\Str; + +/** + * @mixin Builder + */ +trait ReactableEloquentBuilderTrait +{ + public function whereReactedBy( + ReacterableInterface $reacterable, + ?string $reactionTypeName = null, + ): Builder { + return $this->whereHas( + 'loveReactant.reactions', + function (Builder $reactionsQuery) use ( + $reacterable, + $reactionTypeName, + ): void { + $reactionsQuery->where( + 'reacter_id', + $reacterable->getLoveReacter()->getId(), + ); + + if ($reactionTypeName !== null) { + $reactionsQuery->where( + 'reaction_type_id', + ReactionType::fromName($reactionTypeName)->getId(), + ); + } + } + ); + } + + public function whereNotReactedBy( + ReacterableInterface $reacterable, + ?string $reactionTypeName = null, + ): Builder { + return $this->whereDoesntHave( + 'loveReactant.reactions', + function (Builder $reactionsQuery) use ( + $reacterable, + $reactionTypeName, + ): void { + $reactionsQuery->where( + 'reacter_id', + $reacterable->getLoveReacter()->getId(), + ); + + if ($reactionTypeName !== null) { + $reactionsQuery->where( + 'reaction_type_id', + ReactionType::fromName($reactionTypeName)->getId(), + ); + } + } + ); + } + + public function joinReactionCounterOfType( + string $reactionTypeName, + ?string $alias = null, + ): Builder { + $reactionType = ReactionType::fromName($reactionTypeName); + $alias = $alias === null + ? 'reaction_' . Str::snake($reactionType->getName()) + : $alias; + + $select = $this->getQuery()->columns ?? ["{$this->getModel()->getTable()}.*"]; + $select[] = $this->raw("COALESCE({$alias}.count, 0) as {$alias}_count"); + $select[] = $this->raw("COALESCE({$alias}.weight, 0) as {$alias}_weight"); + + return $this + ->leftJoin( + (new ReactionCounter())->getTable() . ' as ' . $alias, + function (JoinClause $join) use ( + $reactionType, + $alias, + ): void { + $join->on( + "{$alias}.reactant_id", + '=', + "{$this->getModel()->getTable()}.love_reactant_id", + ); + $join->where( + "{$alias}.reaction_type_id", + $reactionType->getId(), + ); + } + ) + ->select($select); + } + + public function joinReactionTotal( + ?string $alias = null, + ): Builder { + $alias = $alias === null + ? 'reaction_total' + : $alias; + + $select = $this->getQuery()->columns ?? ["{$this->getModel()->getTable()}.*"]; + $select[] = $this->raw("COALESCE({$alias}.count, 0) as {$alias}_count"); + $select[] = $this->raw("COALESCE({$alias}.weight, 0) as {$alias}_weight"); + + return $this + ->leftJoin( + (new ReactionTotal())->getTable() . ' as ' . $alias, + "{$alias}.reactant_id", + '=', + "{$this->getModel()->getTable()}.love_reactant_id", + ) + ->select($select); + } +} diff --git a/src/Reacterable/Models/Traits/Reacterable.php b/src/Reacterable/Models/Traits/Reacterable.php index d4901f1c..8480f306 100644 --- a/src/Reacterable/Models/Traits/Reacterable.php +++ b/src/Reacterable/Models/Traits/Reacterable.php @@ -13,7 +13,6 @@ namespace Cog\Laravel\Love\Reacterable\Models\Traits; -use Cog\Contracts\Love\Reactable\Models\Reactable as ReactableInterface; use Cog\Contracts\Love\Reacter\Facades\Reacter as ReacterFacadeInterface; use Cog\Contracts\Love\Reacter\Models\Reacter as ReacterInterface; use Cog\Contracts\Love\Reacterable\Exceptions\AlreadyRegisteredAsLoveReacter; @@ -21,8 +20,6 @@ use Cog\Laravel\Love\Reacter\Models\NullReacter; use Cog\Laravel\Love\Reacter\Models\Reacter; use Cog\Laravel\Love\Reacterable\Observers\ReacterableObserver; -use Cog\Laravel\Love\ReactionType\Models\ReactionType; -use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Relations\BelongsTo; /** @@ -74,36 +71,4 @@ public function registerAsLoveReacter(): void $this->setAttribute('love_reacter_id', $reacter->getId()); $this->save(); } - - public function scopeWhereReactedTo( - Builder $query, - ReactableInterface $reactable, - ?string $reactionTypeName = null, - ): Builder { - return $query->whereHas( - 'loveReacter.reactions', - function (Builder $reactionsQuery) use ($reactable, $reactionTypeName) { - $reactionsQuery->where('reactant_id', $reactable->getLoveReactant()->getId()); - if ($reactionTypeName !== null) { - $reactionsQuery->where('reaction_type_id', ReactionType::fromName($reactionTypeName)->getId()); - } - } - ); - } - - public function scopeWhereNotReactedTo( - Builder $query, - ReactableInterface $reactable, - ?string $reactionTypeName = null, - ): Builder { - return $query->whereDoesntHave( - 'loveReacter.reactions', - function (Builder $reactionsQuery) use ($reactable, $reactionTypeName) { - $reactionsQuery->where('reactant_id', $reactable->getLoveReactant()->getId()); - if ($reactionTypeName !== null) { - $reactionsQuery->where('reaction_type_id', ReactionType::fromName($reactionTypeName)->getId()); - } - } - ); - } } diff --git a/src/Reacterable/ReacterableEloquentBuilderTrait.php b/src/Reacterable/ReacterableEloquentBuilderTrait.php new file mode 100644 index 00000000..76fc7f96 --- /dev/null +++ b/src/Reacterable/ReacterableEloquentBuilderTrait.php @@ -0,0 +1,110 @@ + + * + * 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\Laravel\Love\Reacterable; + +use Cog\Contracts\Love\Reactable\Models\Reactable as ReactableInterface; +use Cog\Laravel\Love\Reaction\Models\Reaction; +use Cog\Laravel\Love\ReactionType\Models\ReactionType; +use DateTimeInterface; +use Illuminate\Database\Eloquent\Builder; + +/** + * @mixin Builder + */ +trait ReacterableEloquentBuilderTrait +{ + public function whereReactedTo( + ReactableInterface $reactable, + ?string $reactionTypeName = null, + ): Builder { + return $this->whereHas( + 'loveReacter.reactions', + function (Builder $reactionsQuery) use ( + $reactable, + $reactionTypeName, + ): void { + $reactionsQuery->where( + 'reactant_id', + $reactable->getLoveReactant()->getId(), + ); + + if ($reactionTypeName !== null) { + $reactionsQuery->where( + 'reaction_type_id', + ReactionType::fromName($reactionTypeName)->getId(), + ); + } + } + ); + } + + public function whereNotReactedTo( + ReactableInterface $reactable, + ?string $reactionTypeName = null, + ): Builder { + return $this->whereDoesntHave( + 'loveReacter.reactions', + function (Builder $reactionsQuery) use ( + $reactable, + $reactionTypeName, + ): void { + $reactionsQuery->where( + 'reactant_id', + $reactable->getLoveReactant()->getId(), + ); + + if ($reactionTypeName !== null) { + $reactionsQuery->where( + 'reaction_type_id', + ReactionType::fromName($reactionTypeName)->getId(), + ); + } + } + ); + } + + public function whereReactedToBetween( + ReactableInterface $reactable, + DateTimeInterface $reactedAtFrom, + DateTimeInterface $reactedAtTo, + ?string $reactionTypeName = null, + ): Builder { + return $this->whereHas( + 'loveReacter.reactions', + function (Builder $reactionsQuery) use ( + $reactable, + $reactedAtFrom, + $reactedAtTo, + $reactionTypeName, + ): void { + $reactionsQuery->where( + 'reactant_id', + $reactable->getLoveReactant()->getId(), + ); + + $reactionsQuery->whereBetween( + (new Reaction())->getTable() . '.created_at', + [$reactedAtFrom, $reactedAtTo], + ); + + if ($reactionTypeName !== null) { + $reactionsQuery->where( + 'reaction_type_id', + ReactionType::fromName($reactionTypeName)->getId(), + ); + } + } + ); + } +} diff --git a/tests/Stubs/Models/Article.php b/tests/Stubs/Models/Article.php index 2dd197b6..d3a5dd76 100644 --- a/tests/Stubs/Models/Article.php +++ b/tests/Stubs/Models/Article.php @@ -17,6 +17,9 @@ use Cog\Laravel\Love\Reactable\Models\Traits\Reactable; use Illuminate\Database\Eloquent\Model; +/** + * @method static ArticleEloquentBuilder query() + */ final class Article extends Model implements ReactableInterface { @@ -37,4 +40,10 @@ final class Article extends Model implements protected $fillable = [ 'name', ]; + + /** @inheritDoc */ + public function newEloquentBuilder($query): ArticleEloquentBuilder + { + return new ArticleEloquentBuilder($query); + } } diff --git a/tests/Stubs/Models/ArticleEloquentBuilder.php b/tests/Stubs/Models/ArticleEloquentBuilder.php new file mode 100644 index 00000000..26a1de1f --- /dev/null +++ b/tests/Stubs/Models/ArticleEloquentBuilder.php @@ -0,0 +1,22 @@ + + * + * 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\Laravel\Love\Reactable\ReactableEloquentBuilderTrait; +use Illuminate\Database\Eloquent\Builder; + +final class ArticleEloquentBuilder extends Builder +{ + use ReactableEloquentBuilderTrait; +} diff --git a/tests/Stubs/Models/User.php b/tests/Stubs/Models/User.php index f48784dd..94b7b9c4 100644 --- a/tests/Stubs/Models/User.php +++ b/tests/Stubs/Models/User.php @@ -19,6 +19,9 @@ use Cog\Laravel\Love\Reacterable\Models\Traits\Reacterable; use Illuminate\Foundation\Auth\User as Authenticatable; +/** + * @method static UserEloquentBuilder query() + */ final class User extends Authenticatable implements ReacterableInterface, ReactableInterface @@ -41,4 +44,10 @@ final class User extends Authenticatable implements protected $fillable = [ 'name', ]; + + /** @inheritDoc */ + public function newEloquentBuilder($query): UserEloquentBuilder + { + return new UserEloquentBuilder($query); + } } diff --git a/tests/Stubs/Models/UserEloquentBuilder.php b/tests/Stubs/Models/UserEloquentBuilder.php new file mode 100644 index 00000000..d4e5b8a2 --- /dev/null +++ b/tests/Stubs/Models/UserEloquentBuilder.php @@ -0,0 +1,24 @@ + + * + * 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\Laravel\Love\Reactable\ReactableEloquentBuilderTrait; +use Cog\Laravel\Love\Reacterable\ReacterableEloquentBuilderTrait; +use Illuminate\Database\Eloquent\Builder; + +final class UserEloquentBuilder extends Builder +{ + use ReactableEloquentBuilderTrait; + use ReacterableEloquentBuilderTrait; +} diff --git a/tests/Unit/Reactable/Models/Traits/ReactableTest.php b/tests/Unit/Reactable/Models/Traits/ReactableTest.php index d04ad99c..b29ffd18 100644 --- a/tests/Unit/Reactable/Models/Traits/ReactableTest.php +++ b/tests/Unit/Reactable/Models/Traits/ReactableTest.php @@ -17,13 +17,9 @@ use Cog\Laravel\Love\Reactant\Facades\Reactant as ReactantFacade; use Cog\Laravel\Love\Reactant\Models\NullReactant; use Cog\Laravel\Love\Reactant\Models\Reactant; -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\User; use Cog\Tests\Laravel\Love\TestCase; use Illuminate\Support\Facades\Event; -use Illuminate\Support\Str; final class ReactableTest extends TestCase { @@ -169,1122 +165,4 @@ public function it_throws_exception_on_register_as_love_reactant_when_already_re $article->registerAsLoveReactant(); } - - /** @test */ - public function it_can_scope_by_reacterable(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType = factory(ReactionType::class)->create(); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - $reacterable1 = factory(User::class)->create(); - $reacterable2 = factory(User::class)->create(); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable1->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - 'reacter_id' => $reacterable2->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - 'reacter_id' => $reacterable1->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - 'reacter_id' => $reacterable2->getLoveReacter()->getId(), - ]); - - $reactedByReacterable1 = Article::query() - ->whereReactedBy($reacterable1) - ->get(); - $reactedByReacterable2 = Article::query() - ->whereReactedBy($reacterable2) - ->get(); - - $this->assertSame([ - $reactable1->getKey(), - $reactable3->getKey(), - ], $reactedByReacterable1->pluck('id')->toArray()); - $this->assertSame([ - $reactable2->getKey(), - $reactable3->getKey(), - ], $reactedByReacterable2->pluck('id')->toArray()); - } - - /** @test */ - public function it_can_scope_by_reacterable_and_reaction_type(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType1 = factory(ReactionType::class)->create(); - $reactionType2 = factory(ReactionType::class)->create(); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - $reacterable1 = factory(User::class)->create(); - $reacterable2 = factory(User::class)->create(); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable1->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable2->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - 'reacter_id' => $reacterable1->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - 'reacter_id' => $reacterable2->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - 'reacter_id' => $reacterable1->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - 'reacter_id' => $reacterable2->getLoveReacter()->getId(), - ]); - - $reactedByReacterable1WithReactionType1 = Article::query() - ->whereReactedBy($reacterable1, $reactionType1->getName()) - ->get(); - $reactedByReacterable1WithReactionType2 = Article::query() - ->whereReactedBy($reacterable1, $reactionType2->getName()) - ->get(); - $reactedByReacterable2WithReactionType1 = Article::query() - ->whereReactedBy($reacterable2, $reactionType1->getName()) - ->get(); - $reactedByReacterable2WithReactionType2 = Article::query() - ->whereReactedBy($reacterable2, $reactionType2->getName()) - ->get(); - - $this->assertSame([ - $reactable1->getKey(), - $reactable3->getKey(), - ], $reactedByReacterable1WithReactionType1->pluck('id')->toArray()); - $this->assertSame([ - $reactable2->getKey(), - ], $reactedByReacterable1WithReactionType2->pluck('id')->toArray()); - $this->assertSame([ - $reactable2->getKey(), - $reactable3->getKey(), - ], $reactedByReacterable2WithReactionType1->pluck('id')->toArray()); - $this->assertSame([ - $reactable1->getKey(), - ], $reactedByReacterable2WithReactionType2->pluck('id')->toArray()); - } - - /** @test */ - public function it_can_scope_not_reacted_by_reacterable(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType = factory(ReactionType::class)->create(); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - $reacterable1 = factory(User::class)->create(); - $reacterable2 = factory(User::class)->create(); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable1->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - 'reacter_id' => $reacterable2->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - 'reacter_id' => $reacterable1->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - 'reacter_id' => $reacterable2->getLoveReacter()->getId(), - ]); - - $reactedByReacterable1 = Article::query() - ->whereNotReactedBy($reacterable1) - ->get(); - $reactedByReacterable2 = Article::query() - ->whereNotReactedBy($reacterable2) - ->get(); - - $this->assertSame([ - $reactable2->getKey(), - ], $reactedByReacterable1->pluck('id')->toArray()); - $this->assertSame([ - $reactable1->getKey(), - ], $reactedByReacterable2->pluck('id')->toArray()); - } - - /** @test */ - public function it_can_scope_not_reacted_by_reacterable_and_reaction_type(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType1 = factory(ReactionType::class)->create(); - $reactionType2 = factory(ReactionType::class)->create(); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - $reacterable1 = factory(User::class)->create(); - $reacterable2 = factory(User::class)->create(); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable1->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable2->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - 'reacter_id' => $reacterable1->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - 'reacter_id' => $reacterable2->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - 'reacter_id' => $reacterable1->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - 'reacter_id' => $reacterable2->getLoveReacter()->getId(), - ]); - - $reactedByReacterable1WithReactionType1 = Article::query() - ->whereNotReactedBy($reacterable1, $reactionType1->getName()) - ->get(); - $reactedByReacterable1WithReactionType2 = Article::query() - ->whereNotReactedBy($reacterable1, $reactionType2->getName()) - ->get(); - $reactedByReacterable2WithReactionType1 = Article::query() - ->whereNotReactedBy($reacterable2, $reactionType1->getName()) - ->get(); - $reactedByReacterable2WithReactionType2 = Article::query() - ->whereNotReactedBy($reacterable2, $reactionType2->getName()) - ->get(); - - $this->assertSame([ - $reactable2->getKey(), - ], $reactedByReacterable1WithReactionType1->pluck('id')->toArray()); - $this->assertSame([ - $reactable1->getKey(), - $reactable3->getKey(), - ], $reactedByReacterable1WithReactionType2->pluck('id')->toArray()); - $this->assertSame([ - $reactable1->getKey(), - ], $reactedByReacterable2WithReactionType1->pluck('id')->toArray()); - $this->assertSame([ - $reactable2->getKey(), - $reactable3->getKey(), - ], $reactedByReacterable2WithReactionType2->pluck('id')->toArray()); - } - - /** @test */ - public function it_can_get_reactables_join_reaction_counter_with_type(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType1 = factory(ReactionType::class)->create([ - 'mass' => 2, - ]); - $reactionType2 = factory(ReactionType::class)->create([ - 'mass' => 1, - ]); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 3)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 1)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 4)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 5)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 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() - ->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()); - } - - /** @test */ - public function it_can_get_reactables_join_reaction_counter_with_type_when_type_contains_multiple_words(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType1 = factory(ReactionType::class)->create([ - 'name' => 'SuperLike', - 'mass' => 2, - ]); - $reactionType2 = factory(ReactionType::class)->create([ - 'mass' => 1, - ]); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 3)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 1)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 4)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 5)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 6)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - - $reactionType1CountKey = 'reaction_super_like_count'; - $reactionType1WeightKey = 'reaction_super_like_weight'; - - $reactablesOrderedAsc = Article::query() - ->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()); - } - - /** @test */ - public function it_select_default_reactable_columns_on_get_reactable_join_reaction_counter_with_type(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType1 = factory(ReactionType::class)->create(); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 3)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 1)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - - $reactionType1CountKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_count'; - - $reactablesOrderedAsc = Article::query() - ->joinReactionCounterOfType($reactionType1->getName()) - ->orderBy($reactionType1CountKey, 'asc') - ->get(); - - $this->assertSame([ - $reactable3->id => $reactable3->name, - $reactable1->id => $reactable1->name, - $reactable2->id => $reactable2->name, - ], $reactablesOrderedAsc->pluck('name', 'id')->toArray()); - } - - /** @test */ - public function it_can_select_custom_reactable_columns_on_get_reactable_join_reactions_count_with_type(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType1 = factory(ReactionType::class)->create([ - 'mass' => 2, - ]); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 3)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 1)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - - $reactionType1CountKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_count'; - $reactionType1WeightKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_weight'; - - $reactablesOrderedAsc = Article::query() - ->select('name') - ->joinReactionCounterOfType($reactionType1->getName()) - ->orderBy($reactionType1CountKey, 'asc') - ->get(); - - $this->assertEquals([ - ['name' => $reactable3->name, "$reactionType1CountKey" => 1, "$reactionType1WeightKey" => 2], - ['name' => $reactable1->name, "$reactionType1CountKey" => 2, "$reactionType1WeightKey" => 4], - ['name' => $reactable2->name, "$reactionType1CountKey" => 3, "$reactionType1WeightKey" => 6], - ], $reactablesOrderedAsc->toArray()); - } - - /** @test */ - public function it_can_order_by_total_reactions_count(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType = factory(ReactionType::class)->create(); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 4)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 1)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - - $reactablesOrderedAsc = Article::query() - ->joinReactionTotal() - ->orderBy('reaction_total_count', 'asc') - ->get(); - $reactablesOrderedDesc = Article::query() - ->joinReactionTotal() - ->orderBy('reaction_total_count', 'desc') - ->get(); - - $this->assertEquals([1, 2, 4], $reactablesOrderedAsc->pluck('reaction_total_count')->toArray()); - $this->assertEquals([4, 2, 1], $reactablesOrderedDesc->pluck('reaction_total_count')->toArray()); - } - - /** @test */ - public function it_can_order_by_total_reactions_count_with_custom_alias(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType = factory(ReactionType::class)->create(); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 4)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 1)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - - $reactablesOrderedAsc = Article::query() - ->joinReactionTotal('custom_alias') - ->orderBy('custom_alias_count', 'asc') - ->get(); - $reactablesOrderedDesc = Article::query() - ->joinReactionTotal('custom_alias') - ->orderBy('custom_alias_count', 'desc') - ->get(); - - $this->assertEquals([1, 2, 4], $reactablesOrderedAsc->pluck('custom_alias_count')->toArray()); - $this->assertEquals([4, 2, 1], $reactablesOrderedDesc->pluck('custom_alias_count')->toArray()); - } - - /** @test */ - public function it_select_default_reactable_columns_on_order_by_total_reactions_count(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType = factory(ReactionType::class)->create(); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 4)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 1)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - - $reactablesOrderedAsc = Article::query() - ->joinReactionTotal() - ->orderBy('reaction_total_count', 'asc') - ->get(); - - $this->assertSame([ - $reactable3->id => $reactable3->name, - $reactable1->id => $reactable1->name, - $reactable2->id => $reactable2->name, - ], $reactablesOrderedAsc->pluck('name', 'id')->toArray()); - } - - /** @test */ - public function it_can_select_custom_reactable_columns_on_order_by_total_reactions_count(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType = factory(ReactionType::class)->create(); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 4)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 1)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - - $reactablesOrderedAsc = Article::query() - ->select('name') - ->joinReactionTotal() - ->orderBy('reaction_total_count', 'asc') - ->get(); - - $this->assertEquals([ - ['name' => $reactable3->name, 'reaction_total_count' => 1], - ['name' => $reactable1->name, 'reaction_total_count' => 2], - ['name' => $reactable2->name, 'reaction_total_count' => 4], - ], $reactablesOrderedAsc->map(function (Article $reactable) { - return [ - 'name' => $reactable->getAttributeValue('name'), - 'reaction_total_count' => $reactable->getAttributeValue('reaction_total_count'), - ]; - })->toArray()); - } - - /** @test */ - public function it_can_order_by_reactions_weight(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType = factory(ReactionType::class)->create([ - 'mass' => 2, - ]); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 4)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 1)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - - $reactablesOrderedAsc = Article::query() - ->joinReactionTotal() - ->orderBy('reaction_total_weight', 'asc') - ->get(); - $reactablesOrderedDesc = Article::query() - ->joinReactionTotal() - ->orderBy('reaction_total_weight', 'desc') - ->get(); - - $this->assertEquals([2, 4, 8], $reactablesOrderedAsc->pluck('reaction_total_weight')->toArray()); - $this->assertEquals([8, 4, 2], $reactablesOrderedDesc->pluck('reaction_total_weight')->toArray()); - } - - /** @test */ - public function it_select_default_reactable_columns_on_order_by_reactions_weight(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType = factory(ReactionType::class)->create([ - 'mass' => 2, - ]); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 4)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 1)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - - $reactablesOrderedAsc = Article::query() - ->joinReactionTotal() - ->orderBy('reaction_total_weight', 'asc') - ->get(); - - $this->assertSame([ - $reactable3->id => $reactable3->name, - $reactable1->id => $reactable1->name, - $reactable2->id => $reactable2->name, - ], $reactablesOrderedAsc->pluck('name', 'id')->toArray()); - } - - /** @test */ - public function it_can_select_custom_reactable_columns_on_order_by_reactions_weight(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType = factory(ReactionType::class)->create([ - 'mass' => 2, - ]); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 4)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 1)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - - $reactablesOrderedAsc = Article::query() - ->select('name') - ->joinReactionTotal() - ->orderBy('reaction_total_weight', 'asc') - ->get(); - - $this->assertEquals([ - ['name' => $reactable3->name, 'reaction_total_weight' => 2], - ['name' => $reactable1->name, 'reaction_total_weight' => 4], - ['name' => $reactable2->name, 'reaction_total_weight' => 8], - ], $reactablesOrderedAsc->map(function (Article $reactable) { - return [ - 'name' => $reactable->getAttributeValue('name'), - 'reaction_total_weight' => $reactable->getAttributeValue('reaction_total_weight'), - ]; - })->toArray()); - } - - /** @test */ - public function it_chain_join_reaction_counter_with_type_and_join_reaction_total(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType1 = factory(ReactionType::class)->create([ - 'mass' => 2, - ]); - $reactionType2 = factory(ReactionType::class)->create([ - 'mass' => 1, - ]); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 4)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 1)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - - $reactionType1CountKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_count'; - - $reactablesOrderedAsc = Article::query() - ->joinReactionCounterOfType($reactionType1->getName()) - ->joinReactionTotal() - ->orderBy('reaction_total_weight', 'asc') - ->get(); - - $this->assertEquals([ - [ - 'name' => $reactable3->name, - "$reactionType1CountKey" => 1, - 'reaction_total_count' => 2, - 'reaction_total_weight' => 3, - ], - [ - 'name' => $reactable1->name, - "$reactionType1CountKey" => 2, - 'reaction_total_count' => 3, - 'reaction_total_weight' => 5, - ], - [ - 'name' => $reactable2->name, - "$reactionType1CountKey" => 4, - 'reaction_total_count' => 5, - 'reaction_total_weight' => 9, - ], - ], $reactablesOrderedAsc->map(function (Article $reactable) use ($reactionType1CountKey) { - return [ - 'name' => $reactable->getAttributeValue('name'), - "$reactionType1CountKey" => $reactable->{$reactionType1CountKey}, - 'reaction_total_count' => $reactable->getAttributeValue('reaction_total_count'), - 'reaction_total_weight' => $reactable->getAttributeValue('reaction_total_weight'), - ]; - })->toArray()); - } - - /** @test */ - public function it_include_reaction_total_null_values_replaced_with_zero(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType1 = factory(ReactionType::class)->create([ - 'mass' => 2, - ]); - $reactionType2 = factory(ReactionType::class)->create([ - 'mass' => 1, - ]); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - - $reactablesOrderedAsc = Article::query() - ->joinReactionTotal() - ->orderBy('reaction_total_weight', 'asc') - ->get(); - - $this->assertEquals([ - [ - 'name' => $reactable2->name, - 'reaction_total_count' => 0, - 'reaction_total_weight' => 0, - ], - [ - 'name' => $reactable3->name, - 'reaction_total_count' => 1, - 'reaction_total_weight' => 1, - ], - [ - 'name' => $reactable1->name, - 'reaction_total_count' => 2, - 'reaction_total_weight' => 4, - ], - ], $reactablesOrderedAsc->map(function (Article $reactable) { - return [ - 'name' => $reactable->getAttributeValue('name'), - 'reaction_total_count' => $reactable->getAttributeValue('reaction_total_count'), - 'reaction_total_weight' => $reactable->getAttributeValue('reaction_total_weight'), - ]; - })->toArray()); - } - - /** @test */ - public function it_include_reaction_counter_null_values_replaced_with_zero(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType1 = factory(ReactionType::class)->create([ - 'mass' => 2, - ]); - $reactionType2 = factory(ReactionType::class)->create([ - 'mass' => 1, - ]); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - - $reactionType1CountKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_count'; - - $reactablesOrderedAsc = Article::query() - ->joinReactionCounterOfType($reactionType1->getName()) - ->orderBy($reactionType1CountKey, 'asc') - ->get(); - - $this->assertEquals([ - [ - 'name' => $reactable2->name, - "$reactionType1CountKey" => '0', - ], - [ - 'name' => $reactable3->name, - "$reactionType1CountKey" => '1', - ], - [ - 'name' => $reactable1->name, - "$reactionType1CountKey" => '2', - ], - ], $reactablesOrderedAsc->map(function (Article $reactable) use ($reactionType1CountKey) { - return [ - 'name' => $reactable->getAttributeValue('name'), - "$reactionType1CountKey" => $reactable->{$reactionType1CountKey}, - ]; - })->toArray()); - } - - /** @test */ - public function it_include_null_counter_and_total_values_in_chain_join_reaction_counter_with_type_and_join_reaction_total(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType1 = factory(ReactionType::class)->create([ - 'mass' => 2, - ]); - $reactionType2 = factory(ReactionType::class)->create([ - 'mass' => 1, - ]); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - - $reactionType1CountKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_count'; - - $reactablesOrderedAsc = Article::query() - ->joinReactionCounterOfType($reactionType1->getName()) - ->joinReactionTotal() - ->orderBy('reaction_total_weight', 'asc') - ->get(); - - $this->assertEquals([ - [ - 'name' => $reactable2->name, - "$reactionType1CountKey" => 0, - 'reaction_total_count' => 0, - 'reaction_total_weight' => 0, - ], - [ - 'name' => $reactable3->name, - "$reactionType1CountKey" => 0, - 'reaction_total_count' => 1, - 'reaction_total_weight' => 1, - ], - [ - 'name' => $reactable1->name, - "$reactionType1CountKey" => 2, - 'reaction_total_count' => 2, - 'reaction_total_weight' => 4, - ], - ], $reactablesOrderedAsc->map(function (Article $reactable) use ($reactionType1CountKey) { - return [ - 'name' => $reactable->getAttributeValue('name'), - "$reactionType1CountKey" => $reactable->{$reactionType1CountKey}, - 'reaction_total_count' => $reactable->getAttributeValue('reaction_total_count'), - 'reaction_total_weight' => $reactable->getAttributeValue('reaction_total_weight'), - ]; - })->toArray()); - } - - /** @test */ - public function it_can_chain_multiple_join_reaction_counter_of_type(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType1 = factory(ReactionType::class)->create([ - 'name' => 'Like', - 'mass' => 2, - ]); - $reactionType2 = factory(ReactionType::class)->create([ - 'name' => 'Dislike', - 'mass' => -1, - ]); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - - factory(Reaction::class, 5)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 4)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 3)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 7)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - - $reactablesWithTypeCount = Article::query() - ->joinReactionCounterOfType($reactionType1->getName()) - ->joinReactionCounterOfType($reactionType2->getName()) - ->joinReactionTotal() - ->get(); - - $reactionType1CountKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_count'; - $reactionType1WeightKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_weight'; - $reactionType2CountKey = 'reaction_' . Str::snake($reactionType2->getName()) . '_count'; - $reactionType2WeightKey = 'reaction_' . Str::snake($reactionType2->getName()) . '_weight'; - $this->assertEquals([ - [ - 'name' => $reactable1->name, - "$reactionType1CountKey" => 5, - "$reactionType1WeightKey" => 10, - "$reactionType2CountKey" => 1, - "$reactionType2WeightKey" => -1, - 'reaction_total_weight' => 9, - ], - [ - 'name' => $reactable2->name, - "$reactionType1CountKey" => 4, - "$reactionType1WeightKey" => 8, - "$reactionType2CountKey" => 2, - "$reactionType2WeightKey" => -2, - 'reaction_total_weight' => 6, - ], - [ - 'name' => $reactable3->name, - "$reactionType1CountKey" => 3, - "$reactionType1WeightKey" => 6, - "$reactionType2CountKey" => 7, - "$reactionType2WeightKey" => -7, - 'reaction_total_weight' => -1, - ], - ], $reactablesWithTypeCount->map(function (Article $reactable) use ($reactionType1WeightKey, $reactionType1CountKey, $reactionType2CountKey, $reactionType2WeightKey) { - return [ - 'name' => $reactable->getAttributeValue('name'), - "$reactionType1CountKey" => $reactable->{$reactionType1CountKey}, - "$reactionType1WeightKey" => $reactable->{$reactionType1WeightKey}, - "$reactionType2CountKey" => $reactable->{$reactionType2CountKey}, - "$reactionType2WeightKey" => $reactable->{$reactionType2WeightKey}, - 'reaction_total_weight' => $reactable->getAttributeValue('reaction_total_weight'), - ]; - })->toArray()); - } - - /** @test */ - public function it_can_chain_multiple_join_reaction_counter_of_type_with_custom_aliases(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType1 = factory(ReactionType::class)->create([ - 'name' => 'Like', - 'mass' => 2, - ]); - $reactionType2 = factory(ReactionType::class)->create([ - 'name' => 'Dislike', - 'mass' => -1, - ]); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - $reactable3 = factory(Article::class)->create(); - - factory(Reaction::class, 5)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 4)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 2)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 3)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - factory(Reaction::class, 7)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable3->getLoveReactant()->getId(), - ]); - - $reactablesWithTypeCount = Article::query() - ->joinReactionCounterOfType($reactionType1->getName(), 'likes') - ->joinReactionCounterOfType($reactionType2->getName(), 'custom_alias') - ->get(); - - $reactionType1CountKey = 'likes_count'; - $reactionType1WeightKey = 'likes_weight'; - $reactionType2CountKey = 'custom_alias_count'; - $reactionType2WeightKey = 'custom_alias_weight'; - $this->assertEquals([ - [ - 'name' => $reactable1->name, - "$reactionType1CountKey" => 5, - "$reactionType1WeightKey" => 10, - "$reactionType2CountKey" => 1, - "$reactionType2WeightKey" => -1, - ], - [ - 'name' => $reactable2->name, - "$reactionType1CountKey" => 4, - "$reactionType1WeightKey" => 8, - "$reactionType2CountKey" => 2, - "$reactionType2WeightKey" => -2, - ], - [ - 'name' => $reactable3->name, - "$reactionType1CountKey" => 3, - "$reactionType1WeightKey" => 6, - "$reactionType2CountKey" => 7, - "$reactionType2WeightKey" => -7, - ], - ], $reactablesWithTypeCount->map(function (Article $reactable) use ($reactionType1WeightKey, $reactionType1CountKey, $reactionType2CountKey, $reactionType2WeightKey) { - return [ - 'name' => $reactable->getAttributeValue('name'), - "$reactionType1CountKey" => $reactable->{$reactionType1CountKey}, - "$reactionType1WeightKey" => $reactable->{$reactionType1WeightKey}, - "$reactionType2CountKey" => $reactable->{$reactionType2CountKey}, - "$reactionType2WeightKey" => $reactable->{$reactionType2WeightKey}, - ]; - })->toArray()); - } } diff --git a/tests/Unit/Reactable/ReactableEloquentBuilderTraitTest.php b/tests/Unit/Reactable/ReactableEloquentBuilderTraitTest.php new file mode 100644 index 00000000..f9e147ed --- /dev/null +++ b/tests/Unit/Reactable/ReactableEloquentBuilderTraitTest.php @@ -0,0 +1,1143 @@ + + * + * 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\Unit\Reactable; + +use Cog\Laravel\Love\Reactant\Models\Reactant; +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\User; +use Cog\Tests\Laravel\Love\TestCase; +use Illuminate\Support\Str; + +final class ReactableEloquentBuilderTraitTest extends TestCase +{ + /** @test */ + public function it_can_scope_by_reacterable(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType = factory(ReactionType::class)->create(); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + $reacterable1 = factory(User::class)->create(); + $reacterable2 = factory(User::class)->create(); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + ]); + + $reactedByReacterable1 = Article::query() + ->whereReactedBy($reacterable1) + ->get(); + $reactedByReacterable2 = Article::query() + ->whereReactedBy($reacterable2) + ->get(); + + $this->assertSame([ + $reactable1->getKey(), + $reactable3->getKey(), + ], $reactedByReacterable1->pluck('id')->toArray()); + $this->assertSame([ + $reactable2->getKey(), + $reactable3->getKey(), + ], $reactedByReacterable2->pluck('id')->toArray()); + } + + /** @test */ + public function it_can_scope_by_reacterable_and_reaction_type(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType1 = factory(ReactionType::class)->create(); + $reactionType2 = factory(ReactionType::class)->create(); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + $reacterable1 = factory(User::class)->create(); + $reacterable2 = factory(User::class)->create(); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + ]); + + $reactedByReacterable1WithReactionType1 = Article::query() + ->whereReactedBy($reacterable1, $reactionType1->getName()) + ->get(); + $reactedByReacterable1WithReactionType2 = Article::query() + ->whereReactedBy($reacterable1, $reactionType2->getName()) + ->get(); + $reactedByReacterable2WithReactionType1 = Article::query() + ->whereReactedBy($reacterable2, $reactionType1->getName()) + ->get(); + $reactedByReacterable2WithReactionType2 = Article::query() + ->whereReactedBy($reacterable2, $reactionType2->getName()) + ->get(); + + $this->assertSame([ + $reactable1->getKey(), + $reactable3->getKey(), + ], $reactedByReacterable1WithReactionType1->pluck('id')->toArray()); + $this->assertSame([ + $reactable2->getKey(), + ], $reactedByReacterable1WithReactionType2->pluck('id')->toArray()); + $this->assertSame([ + $reactable2->getKey(), + $reactable3->getKey(), + ], $reactedByReacterable2WithReactionType1->pluck('id')->toArray()); + $this->assertSame([ + $reactable1->getKey(), + ], $reactedByReacterable2WithReactionType2->pluck('id')->toArray()); + } + + /** @test */ + public function it_can_scope_not_reacted_by_reacterable(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType = factory(ReactionType::class)->create(); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + $reacterable1 = factory(User::class)->create(); + $reacterable2 = factory(User::class)->create(); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + ]); + + $reactedByReacterable1 = Article::query() + ->whereNotReactedBy($reacterable1) + ->get(); + $reactedByReacterable2 = Article::query() + ->whereNotReactedBy($reacterable2) + ->get(); + + $this->assertSame([ + $reactable2->getKey(), + ], $reactedByReacterable1->pluck('id')->toArray()); + $this->assertSame([ + $reactable1->getKey(), + ], $reactedByReacterable2->pluck('id')->toArray()); + } + + /** @test */ + public function it_can_scope_not_reacted_by_reacterable_and_reaction_type(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType1 = factory(ReactionType::class)->create(); + $reactionType2 = factory(ReactionType::class)->create(); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + $reacterable1 = factory(User::class)->create(); + $reacterable2 = factory(User::class)->create(); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + ]); + + $reactedByReacterable1WithReactionType1 = Article::query() + ->whereNotReactedBy($reacterable1, $reactionType1->getName()) + ->get(); + $reactedByReacterable1WithReactionType2 = Article::query() + ->whereNotReactedBy($reacterable1, $reactionType2->getName()) + ->get(); + $reactedByReacterable2WithReactionType1 = Article::query() + ->whereNotReactedBy($reacterable2, $reactionType1->getName()) + ->get(); + $reactedByReacterable2WithReactionType2 = Article::query() + ->whereNotReactedBy($reacterable2, $reactionType2->getName()) + ->get(); + + $this->assertSame([ + $reactable2->getKey(), + ], $reactedByReacterable1WithReactionType1->pluck('id')->toArray()); + $this->assertSame([ + $reactable1->getKey(), + $reactable3->getKey(), + ], $reactedByReacterable1WithReactionType2->pluck('id')->toArray()); + $this->assertSame([ + $reactable1->getKey(), + ], $reactedByReacterable2WithReactionType1->pluck('id')->toArray()); + $this->assertSame([ + $reactable2->getKey(), + $reactable3->getKey(), + ], $reactedByReacterable2WithReactionType2->pluck('id')->toArray()); + } + + /** @test */ + public function it_can_get_reactables_join_reaction_counter_with_type(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType1 = factory(ReactionType::class)->create([ + 'mass' => 2, + ]); + $reactionType2 = factory(ReactionType::class)->create([ + 'mass' => 1, + ]); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 3)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 1)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 4)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 5)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 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() + ->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()); + } + + /** @test */ + public function it_can_get_reactables_join_reaction_counter_with_type_when_type_contains_multiple_words(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType1 = factory(ReactionType::class)->create([ + 'name' => 'SuperLike', + 'mass' => 2, + ]); + $reactionType2 = factory(ReactionType::class)->create([ + 'mass' => 1, + ]); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 3)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 1)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 4)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 5)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 6)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + + $reactionType1CountKey = 'reaction_super_like_count'; + $reactionType1WeightKey = 'reaction_super_like_weight'; + + $reactablesOrderedAsc = Article::query() + ->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()); + } + + /** @test */ + public function it_select_default_reactable_columns_on_get_reactable_join_reaction_counter_with_type(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType1 = factory(ReactionType::class)->create(); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 3)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 1)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + + $reactionType1CountKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_count'; + + $reactablesOrderedAsc = Article::query() + ->joinReactionCounterOfType($reactionType1->getName()) + ->orderBy($reactionType1CountKey, 'asc') + ->get(); + + $this->assertSame([ + $reactable3->id => $reactable3->name, + $reactable1->id => $reactable1->name, + $reactable2->id => $reactable2->name, + ], $reactablesOrderedAsc->pluck('name', 'id')->toArray()); + } + + /** @test */ + public function it_can_select_custom_reactable_columns_on_get_reactable_join_reactions_count_with_type(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType1 = factory(ReactionType::class)->create([ + 'mass' => 2, + ]); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 3)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 1)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + + $reactionType1CountKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_count'; + $reactionType1WeightKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_weight'; + + $reactablesOrderedAsc = Article::query() + ->select('name') + ->joinReactionCounterOfType($reactionType1->getName()) + ->orderBy($reactionType1CountKey, 'asc') + ->get(); + + $this->assertEquals([ + ['name' => $reactable3->name, "$reactionType1CountKey" => 1, "$reactionType1WeightKey" => 2], + ['name' => $reactable1->name, "$reactionType1CountKey" => 2, "$reactionType1WeightKey" => 4], + ['name' => $reactable2->name, "$reactionType1CountKey" => 3, "$reactionType1WeightKey" => 6], + ], $reactablesOrderedAsc->toArray()); + } + + /** @test */ + public function it_can_order_by_total_reactions_count(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType = factory(ReactionType::class)->create(); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 4)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 1)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + + $reactablesOrderedAsc = Article::query() + ->joinReactionTotal() + ->orderBy('reaction_total_count', 'asc') + ->get(); + $reactablesOrderedDesc = Article::query() + ->joinReactionTotal() + ->orderBy('reaction_total_count', 'desc') + ->get(); + + $this->assertEquals([1, 2, 4], $reactablesOrderedAsc->pluck('reaction_total_count')->toArray()); + $this->assertEquals([4, 2, 1], $reactablesOrderedDesc->pluck('reaction_total_count')->toArray()); + } + + /** @test */ + public function it_can_order_by_total_reactions_count_with_custom_alias(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType = factory(ReactionType::class)->create(); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 4)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 1)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + + $reactablesOrderedAsc = Article::query() + ->joinReactionTotal('custom_alias') + ->orderBy('custom_alias_count', 'asc') + ->get(); + $reactablesOrderedDesc = Article::query() + ->joinReactionTotal('custom_alias') + ->orderBy('custom_alias_count', 'desc') + ->get(); + + $this->assertEquals([1, 2, 4], $reactablesOrderedAsc->pluck('custom_alias_count')->toArray()); + $this->assertEquals([4, 2, 1], $reactablesOrderedDesc->pluck('custom_alias_count')->toArray()); + } + + /** @test */ + public function it_select_default_reactable_columns_on_order_by_total_reactions_count(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType = factory(ReactionType::class)->create(); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 4)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 1)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + + $reactablesOrderedAsc = Article::query() + ->joinReactionTotal() + ->orderBy('reaction_total_count', 'asc') + ->get(); + + $this->assertSame([ + $reactable3->id => $reactable3->name, + $reactable1->id => $reactable1->name, + $reactable2->id => $reactable2->name, + ], $reactablesOrderedAsc->pluck('name', 'id')->toArray()); + } + + /** @test */ + public function it_can_select_custom_reactable_columns_on_order_by_total_reactions_count(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType = factory(ReactionType::class)->create(); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 4)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 1)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + + $reactablesOrderedAsc = Article::query() + ->select('name') + ->joinReactionTotal() + ->orderBy('reaction_total_count', 'asc') + ->get(); + + $this->assertEquals([ + ['name' => $reactable3->name, 'reaction_total_count' => 1], + ['name' => $reactable1->name, 'reaction_total_count' => 2], + ['name' => $reactable2->name, 'reaction_total_count' => 4], + ], $reactablesOrderedAsc->map(function (Article $reactable) { + return [ + 'name' => $reactable->getAttributeValue('name'), + 'reaction_total_count' => $reactable->getAttributeValue('reaction_total_count'), + ]; + })->toArray()); + } + + /** @test */ + public function it_can_order_by_reactions_weight(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType = factory(ReactionType::class)->create([ + 'mass' => 2, + ]); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 4)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 1)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + + $reactablesOrderedAsc = Article::query() + ->joinReactionTotal() + ->orderBy('reaction_total_weight', 'asc') + ->get(); + $reactablesOrderedDesc = Article::query() + ->joinReactionTotal() + ->orderBy('reaction_total_weight', 'desc') + ->get(); + + $this->assertEquals([2, 4, 8], $reactablesOrderedAsc->pluck('reaction_total_weight')->toArray()); + $this->assertEquals([8, 4, 2], $reactablesOrderedDesc->pluck('reaction_total_weight')->toArray()); + } + + /** @test */ + public function it_select_default_reactable_columns_on_order_by_reactions_weight(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType = factory(ReactionType::class)->create([ + 'mass' => 2, + ]); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 4)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 1)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + + $reactablesOrderedAsc = Article::query() + ->joinReactionTotal() + ->orderBy('reaction_total_weight', 'asc') + ->get(); + + $this->assertSame([ + $reactable3->id => $reactable3->name, + $reactable1->id => $reactable1->name, + $reactable2->id => $reactable2->name, + ], $reactablesOrderedAsc->pluck('name', 'id')->toArray()); + } + + /** @test */ + public function it_can_select_custom_reactable_columns_on_order_by_reactions_weight(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType = factory(ReactionType::class)->create([ + 'mass' => 2, + ]); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 4)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 1)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + + $reactablesOrderedAsc = Article::query() + ->select('name') + ->joinReactionTotal() + ->orderBy('reaction_total_weight', 'asc') + ->get(); + + $this->assertEquals([ + ['name' => $reactable3->name, 'reaction_total_weight' => 2], + ['name' => $reactable1->name, 'reaction_total_weight' => 4], + ['name' => $reactable2->name, 'reaction_total_weight' => 8], + ], $reactablesOrderedAsc->map(function (Article $reactable) { + return [ + 'name' => $reactable->getAttributeValue('name'), + 'reaction_total_weight' => $reactable->getAttributeValue('reaction_total_weight'), + ]; + })->toArray()); + } + + /** @test */ + public function it_chain_join_reaction_counter_with_type_and_join_reaction_total(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType1 = factory(ReactionType::class)->create([ + 'mass' => 2, + ]); + $reactionType2 = factory(ReactionType::class)->create([ + 'mass' => 1, + ]); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 4)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 1)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + + $reactionType1CountKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_count'; + + $reactablesOrderedAsc = Article::query() + ->joinReactionCounterOfType($reactionType1->getName()) + ->joinReactionTotal() + ->orderBy('reaction_total_weight', 'asc') + ->get(); + + $this->assertEquals([ + [ + 'name' => $reactable3->name, + "$reactionType1CountKey" => 1, + 'reaction_total_count' => 2, + 'reaction_total_weight' => 3, + ], + [ + 'name' => $reactable1->name, + "$reactionType1CountKey" => 2, + 'reaction_total_count' => 3, + 'reaction_total_weight' => 5, + ], + [ + 'name' => $reactable2->name, + "$reactionType1CountKey" => 4, + 'reaction_total_count' => 5, + 'reaction_total_weight' => 9, + ], + ], $reactablesOrderedAsc->map(function (Article $reactable) use ($reactionType1CountKey) { + return [ + 'name' => $reactable->getAttributeValue('name'), + "$reactionType1CountKey" => $reactable->{$reactionType1CountKey}, + 'reaction_total_count' => $reactable->getAttributeValue('reaction_total_count'), + 'reaction_total_weight' => $reactable->getAttributeValue('reaction_total_weight'), + ]; + })->toArray()); + } + + /** @test */ + public function it_include_reaction_total_null_values_replaced_with_zero(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType1 = factory(ReactionType::class)->create([ + 'mass' => 2, + ]); + $reactionType2 = factory(ReactionType::class)->create([ + 'mass' => 1, + ]); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + + $reactablesOrderedAsc = Article::query() + ->joinReactionTotal() + ->orderBy('reaction_total_weight', 'asc') + ->get(); + + $this->assertEquals([ + [ + 'name' => $reactable2->name, + 'reaction_total_count' => 0, + 'reaction_total_weight' => 0, + ], + [ + 'name' => $reactable3->name, + 'reaction_total_count' => 1, + 'reaction_total_weight' => 1, + ], + [ + 'name' => $reactable1->name, + 'reaction_total_count' => 2, + 'reaction_total_weight' => 4, + ], + ], $reactablesOrderedAsc->map(function (Article $reactable) { + return [ + 'name' => $reactable->getAttributeValue('name'), + 'reaction_total_count' => $reactable->getAttributeValue('reaction_total_count'), + 'reaction_total_weight' => $reactable->getAttributeValue('reaction_total_weight'), + ]; + })->toArray()); + } + + /** @test */ + public function it_include_reaction_counter_null_values_replaced_with_zero(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType1 = factory(ReactionType::class)->create([ + 'mass' => 2, + ]); + $reactionType2 = factory(ReactionType::class)->create([ + 'mass' => 1, + ]); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + + $reactionType1CountKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_count'; + + $reactablesOrderedAsc = Article::query() + ->joinReactionCounterOfType($reactionType1->getName()) + ->orderBy($reactionType1CountKey, 'asc') + ->get(); + + $this->assertEquals([ + [ + 'name' => $reactable2->name, + "$reactionType1CountKey" => '0', + ], + [ + 'name' => $reactable3->name, + "$reactionType1CountKey" => '1', + ], + [ + 'name' => $reactable1->name, + "$reactionType1CountKey" => '2', + ], + ], $reactablesOrderedAsc->map(function (Article $reactable) use ($reactionType1CountKey) { + return [ + 'name' => $reactable->getAttributeValue('name'), + "$reactionType1CountKey" => $reactable->{$reactionType1CountKey}, + ]; + })->toArray()); + } + + /** @test */ + public function it_include_null_counter_and_total_values_in_chain_join_reaction_counter_with_type_and_join_reaction_total(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType1 = factory(ReactionType::class)->create([ + 'mass' => 2, + ]); + $reactionType2 = factory(ReactionType::class)->create([ + 'mass' => 1, + ]); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + + $reactionType1CountKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_count'; + + $reactablesOrderedAsc = Article::query() + ->joinReactionCounterOfType($reactionType1->getName()) + ->joinReactionTotal() + ->orderBy('reaction_total_weight', 'asc') + ->get(); + + $this->assertEquals([ + [ + 'name' => $reactable2->name, + "$reactionType1CountKey" => 0, + 'reaction_total_count' => 0, + 'reaction_total_weight' => 0, + ], + [ + 'name' => $reactable3->name, + "$reactionType1CountKey" => 0, + 'reaction_total_count' => 1, + 'reaction_total_weight' => 1, + ], + [ + 'name' => $reactable1->name, + "$reactionType1CountKey" => 2, + 'reaction_total_count' => 2, + 'reaction_total_weight' => 4, + ], + ], $reactablesOrderedAsc->map(function (Article $reactable) use ($reactionType1CountKey) { + return [ + 'name' => $reactable->getAttributeValue('name'), + "$reactionType1CountKey" => $reactable->{$reactionType1CountKey}, + 'reaction_total_count' => $reactable->getAttributeValue('reaction_total_count'), + 'reaction_total_weight' => $reactable->getAttributeValue('reaction_total_weight'), + ]; + })->toArray()); + } + + /** @test */ + public function it_can_chain_multiple_join_reaction_counter_of_type(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType1 = factory(ReactionType::class)->create([ + 'name' => 'Like', + 'mass' => 2, + ]); + $reactionType2 = factory(ReactionType::class)->create([ + 'name' => 'Dislike', + 'mass' => -1, + ]); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + + factory(Reaction::class, 5)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 4)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 3)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 7)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + + $reactablesWithTypeCount = Article::query() + ->joinReactionCounterOfType($reactionType1->getName()) + ->joinReactionCounterOfType($reactionType2->getName()) + ->joinReactionTotal() + ->get(); + + $reactionType1CountKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_count'; + $reactionType1WeightKey = 'reaction_' . Str::snake($reactionType1->getName()) . '_weight'; + $reactionType2CountKey = 'reaction_' . Str::snake($reactionType2->getName()) . '_count'; + $reactionType2WeightKey = 'reaction_' . Str::snake($reactionType2->getName()) . '_weight'; + $this->assertEquals([ + [ + 'name' => $reactable1->name, + "$reactionType1CountKey" => 5, + "$reactionType1WeightKey" => 10, + "$reactionType2CountKey" => 1, + "$reactionType2WeightKey" => -1, + 'reaction_total_weight' => 9, + ], + [ + 'name' => $reactable2->name, + "$reactionType1CountKey" => 4, + "$reactionType1WeightKey" => 8, + "$reactionType2CountKey" => 2, + "$reactionType2WeightKey" => -2, + 'reaction_total_weight' => 6, + ], + [ + 'name' => $reactable3->name, + "$reactionType1CountKey" => 3, + "$reactionType1WeightKey" => 6, + "$reactionType2CountKey" => 7, + "$reactionType2WeightKey" => -7, + 'reaction_total_weight' => -1, + ], + ], $reactablesWithTypeCount->map(function (Article $reactable) use ($reactionType1WeightKey, $reactionType1CountKey, $reactionType2CountKey, $reactionType2WeightKey) { + return [ + 'name' => $reactable->getAttributeValue('name'), + "$reactionType1CountKey" => $reactable->{$reactionType1CountKey}, + "$reactionType1WeightKey" => $reactable->{$reactionType1WeightKey}, + "$reactionType2CountKey" => $reactable->{$reactionType2CountKey}, + "$reactionType2WeightKey" => $reactable->{$reactionType2WeightKey}, + 'reaction_total_weight' => $reactable->getAttributeValue('reaction_total_weight'), + ]; + })->toArray()); + } + + /** @test */ + public function it_can_chain_multiple_join_reaction_counter_of_type_with_custom_aliases(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType1 = factory(ReactionType::class)->create([ + 'name' => 'Like', + 'mass' => 2, + ]); + $reactionType2 = factory(ReactionType::class)->create([ + 'name' => 'Dislike', + 'mass' => -1, + ]); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + $reactable3 = factory(Article::class)->create(); + + factory(Reaction::class, 5)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 4)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 2)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 3)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + factory(Reaction::class, 7)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable3->getLoveReactant()->getId(), + ]); + + $reactablesWithTypeCount = Article::query() + ->joinReactionCounterOfType($reactionType1->getName(), 'likes') + ->joinReactionCounterOfType($reactionType2->getName(), 'custom_alias') + ->get(); + + $reactionType1CountKey = 'likes_count'; + $reactionType1WeightKey = 'likes_weight'; + $reactionType2CountKey = 'custom_alias_count'; + $reactionType2WeightKey = 'custom_alias_weight'; + $this->assertEquals([ + [ + 'name' => $reactable1->name, + "$reactionType1CountKey" => 5, + "$reactionType1WeightKey" => 10, + "$reactionType2CountKey" => 1, + "$reactionType2WeightKey" => -1, + ], + [ + 'name' => $reactable2->name, + "$reactionType1CountKey" => 4, + "$reactionType1WeightKey" => 8, + "$reactionType2CountKey" => 2, + "$reactionType2WeightKey" => -2, + ], + [ + 'name' => $reactable3->name, + "$reactionType1CountKey" => 3, + "$reactionType1WeightKey" => 6, + "$reactionType2CountKey" => 7, + "$reactionType2WeightKey" => -7, + ], + ], $reactablesWithTypeCount->map(function (Article $reactable) use ($reactionType1WeightKey, $reactionType1CountKey, $reactionType2CountKey, $reactionType2WeightKey) { + return [ + 'name' => $reactable->getAttributeValue('name'), + "$reactionType1CountKey" => $reactable->{$reactionType1CountKey}, + "$reactionType1WeightKey" => $reactable->{$reactionType1WeightKey}, + "$reactionType2CountKey" => $reactable->{$reactionType2CountKey}, + "$reactionType2WeightKey" => $reactable->{$reactionType2WeightKey}, + ]; + })->toArray()); + } +} diff --git a/tests/Unit/Reacterable/Models/Traits/ReacterableTest.php b/tests/Unit/Reacterable/Models/Traits/ReacterableTest.php index 608db1c9..fec07765 100644 --- a/tests/Unit/Reacterable/Models/Traits/ReacterableTest.php +++ b/tests/Unit/Reacterable/Models/Traits/ReacterableTest.php @@ -14,13 +14,9 @@ namespace Cog\Tests\Laravel\Love\Unit\Reacterable\Models\Traits; use Cog\Contracts\Love\Reacterable\Exceptions\AlreadyRegisteredAsLoveReacter; -use Cog\Laravel\Love\Reactant\Models\Reactant; use Cog\Laravel\Love\Reacter\Facades\Reacter as ReacterFacade; use Cog\Laravel\Love\Reacter\Models\NullReacter; use Cog\Laravel\Love\Reacter\Models\Reacter; -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\Bot; use Cog\Tests\Laravel\Love\Stubs\Models\User; use Cog\Tests\Laravel\Love\TestCase; @@ -170,240 +166,4 @@ public function it_throws_exception_on_register_as_love_reacter_when_already_reg $user->registerAsLoveReacter(); } - - /** @test */ - public function it_can_scope_reacted_to_reactable(): void - { - factory(Reacter::class)->create(); // Needed to has not same ids with Reacter - $reactionType = factory(ReactionType::class)->create(); - $reacterable1 = factory(User::class)->create(); - $reacterable2 = factory(User::class)->create(); - $reacterable3 = factory(User::class)->create(); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable1->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable2->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable3->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - 'reacter_id' => $reacterable3->getLoveReacter()->getId(), - ]); - - $reactedToReactable1 = User::query() - ->whereReactedTo($reactable1) - ->get(); - $reactedToReactable2 = User::query() - ->whereReactedTo($reactable2) - ->get(); - - $this->assertSame([ - $reacterable1->getKey(), - $reacterable2->getKey(), - $reacterable3->getKey(), - ], $reactedToReactable1->pluck('id')->toArray()); - $this->assertSame([ - $reacterable3->getKey(), - ], $reactedToReactable2->pluck('id')->toArray()); - } - - /** @test */ - public function it_can_scope_reacted_to_reactable_and_reaction_type(): void - { - factory(Reacter::class)->create(); // Needed to has not same ids with Reacter - $reactionType1 = factory(ReactionType::class)->create(); - $reactionType2 = factory(ReactionType::class)->create(); - $reacterable1 = factory(User::class)->create(); - $reacterable2 = factory(User::class)->create(); - $reacterable3 = factory(User::class)->create(); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable1->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable2->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - 'reacter_id' => $reacterable1->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - 'reacter_id' => $reacterable2->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable3->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - 'reacter_id' => $reacterable3->getLoveReacter()->getId(), - ]); - - $reactedToReactable1WithReactionType1 = User::query() - ->whereReactedTo($reactable1, $reactionType1->getName()) - ->get(); - $reactedToReactable1WithReactionType2 = User::query() - ->whereReactedTo($reactable1, $reactionType2->getName()) - ->get(); - $reactedToReactable2WithReactionType1 = User::query() - ->whereReactedTo($reactable2, $reactionType1->getName()) - ->get(); - $reactedToReactable2WithReactionType2 = User::query() - ->whereReactedTo($reactable2, $reactionType2->getName()) - ->get(); - - $this->assertSame([ - $reacterable1->getKey(), - $reacterable3->getKey(), - ], $reactedToReactable1WithReactionType1->pluck('id')->toArray()); - $this->assertSame([ - $reacterable2->getKey(), - ], $reactedToReactable1WithReactionType2->pluck('id')->toArray()); - $this->assertSame([ - $reacterable2->getKey(), - $reacterable3->getKey(), - ], $reactedToReactable2WithReactionType1->pluck('id')->toArray()); - $this->assertSame([ - $reacterable1->getKey(), - ], $reactedToReactable2WithReactionType2->pluck('id')->toArray()); - } - - /** @test */ - public function it_can_scope_not_reacted_to_reactable(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType = factory(ReactionType::class)->create(); - $reacterable1 = factory(User::class)->create(); - $reacterable2 = factory(User::class)->create(); - $reacterable3 = factory(User::class)->create(); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable1->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - 'reacter_id' => $reacterable2->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable3->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - 'reacter_id' => $reacterable3->getLoveReacter()->getId(), - ]); - - $reactedToReactable1 = User::query() - ->whereNotReactedTo($reactable1) - ->get(); - $reactedToReactable2 = User::query() - ->whereNotReactedTo($reactable2) - ->get(); - - $this->assertSame([ - $reactable2->getKey(), - ], $reactedToReactable1->pluck('id')->toArray()); - $this->assertSame([ - $reactable1->getKey(), - ], $reactedToReactable2->pluck('id')->toArray()); - } - - /** @test */ - public function it_can_scope_not_reacted_to_reactable_and_reaction_type(): void - { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant - $reactionType1 = factory(ReactionType::class)->create(); - $reactionType2 = factory(ReactionType::class)->create(); - $reacterable1 = factory(User::class)->create(); - $reacterable2 = factory(User::class)->create(); - $reacterable3 = factory(User::class)->create(); - $reactable1 = factory(Article::class)->create(); - $reactable2 = factory(Article::class)->create(); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable1->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable2->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType2->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - 'reacter_id' => $reacterable1->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - 'reacter_id' => $reacterable2->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable1->getLoveReactant()->getId(), - 'reacter_id' => $reacterable3->getLoveReacter()->getId(), - ]); - factory(Reaction::class)->create([ - 'reaction_type_id' => $reactionType1->getId(), - 'reactant_id' => $reactable2->getLoveReactant()->getId(), - 'reacter_id' => $reacterable3->getLoveReacter()->getId(), - ]); - - $reactedToReactable1WithReactionType1 = User::query() - ->whereNotReactedTo($reactable1, $reactionType1->getName()) - ->get(); - $reactedToReactable1WithReactionType2 = User::query() - ->whereNotReactedTo($reactable1, $reactionType2->getName()) - ->get(); - $reactedToReactable2WithReactionType1 = User::query() - ->whereNotReactedTo($reactable2, $reactionType1->getName()) - ->get(); - $reactedToReactable2WithReactionType2 = User::query() - ->whereNotReactedTo($reactable2, $reactionType2->getName()) - ->get(); - - $this->assertSame([ - $reacterable2->getKey(), - ], $reactedToReactable1WithReactionType1->pluck('id')->toArray()); - $this->assertSame([ - $reacterable1->getKey(), - $reacterable3->getKey(), - ], $reactedToReactable1WithReactionType2->pluck('id')->toArray()); - $this->assertSame([ - $reacterable1->getKey(), - ], $reactedToReactable2WithReactionType1->pluck('id')->toArray()); - $this->assertSame([ - $reacterable2->getKey(), - $reacterable3->getKey(), - ], $reactedToReactable2WithReactionType2->pluck('id')->toArray()); - } } diff --git a/tests/Unit/Reacterable/ReacterableEloquentBuilderTraitTest.php b/tests/Unit/Reacterable/ReacterableEloquentBuilderTraitTest.php new file mode 100644 index 00000000..a74589bb --- /dev/null +++ b/tests/Unit/Reacterable/ReacterableEloquentBuilderTraitTest.php @@ -0,0 +1,311 @@ + + * + * 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\Unit\Reacterable; + +use Cog\Laravel\Love\Reactant\Models\Reactant; +use Cog\Laravel\Love\Reacter\Models\Reacter; +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\User; +use Cog\Tests\Laravel\Love\TestCase; +use DateTimeImmutable; + +final class ReacterableEloquentBuilderTraitTest extends TestCase +{ + /** @test */ + public function it_can_scope_reacted_to_reactable(): void + { + factory(Reacter::class)->create(); // Needed to has not same ids with Reacter + $reactionType = factory(ReactionType::class)->create(); + $reacterable1 = factory(User::class)->create(); + $reacterable2 = factory(User::class)->create(); + $reacterable3 = factory(User::class)->create(); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable3->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + 'reacter_id' => $reacterable3->getLoveReacter()->getId(), + ]); + + $reactedToReactable1 = User::query() + ->whereReactedTo($reactable1) + ->get(); + $reactedToReactable2 = User::query() + ->whereReactedTo($reactable2) + ->get(); + + $this->assertSame([ + $reacterable1->getKey(), + $reacterable2->getKey(), + $reacterable3->getKey(), + ], $reactedToReactable1->pluck('id')->toArray()); + $this->assertSame([ + $reacterable3->getKey(), + ], $reactedToReactable2->pluck('id')->toArray()); + } + + /** @test */ + public function it_can_scope_reacted_to_reactable_and_reaction_type(): void + { + factory(Reacter::class)->create(); // Needed to has not same ids with Reacter + $reactionType1 = factory(ReactionType::class)->create(); + $reactionType2 = factory(ReactionType::class)->create(); + $reacterable1 = factory(User::class)->create(); + $reacterable2 = factory(User::class)->create(); + $reacterable3 = factory(User::class)->create(); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable3->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + 'reacter_id' => $reacterable3->getLoveReacter()->getId(), + ]); + + $reactedToReactable1WithReactionType1 = User::query() + ->whereReactedTo($reactable1, $reactionType1->getName()) + ->get(); + $reactedToReactable1WithReactionType2 = User::query() + ->whereReactedTo($reactable1, $reactionType2->getName()) + ->get(); + $reactedToReactable2WithReactionType1 = User::query() + ->whereReactedTo($reactable2, $reactionType1->getName()) + ->get(); + $reactedToReactable2WithReactionType2 = User::query() + ->whereReactedTo($reactable2, $reactionType2->getName()) + ->get(); + + $this->assertSame([ + $reacterable1->getKey(), + $reacterable3->getKey(), + ], $reactedToReactable1WithReactionType1->pluck('id')->toArray()); + $this->assertSame([ + $reacterable2->getKey(), + ], $reactedToReactable1WithReactionType2->pluck('id')->toArray()); + $this->assertSame([ + $reacterable2->getKey(), + $reacterable3->getKey(), + ], $reactedToReactable2WithReactionType1->pluck('id')->toArray()); + $this->assertSame([ + $reacterable1->getKey(), + ], $reactedToReactable2WithReactionType2->pluck('id')->toArray()); + } + + /** @test */ + public function it_can_scope_not_reacted_to_reactable(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType = factory(ReactionType::class)->create(); + $reacterable1 = factory(User::class)->create(); + $reacterable2 = factory(User::class)->create(); + $reacterable3 = factory(User::class)->create(); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable3->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + 'reacter_id' => $reacterable3->getLoveReacter()->getId(), + ]); + + $reactedToReactable1 = User::query() + ->whereNotReactedTo($reactable1) + ->get(); + $reactedToReactable2 = User::query() + ->whereNotReactedTo($reactable2) + ->get(); + + $this->assertSame([ + $reactable2->getKey(), + ], $reactedToReactable1->pluck('id')->toArray()); + $this->assertSame([ + $reactable1->getKey(), + ], $reactedToReactable2->pluck('id')->toArray()); + } + + /** @test */ + public function it_can_scope_not_reacted_to_reactable_and_reaction_type(): void + { + factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + $reactionType1 = factory(ReactionType::class)->create(); + $reactionType2 = factory(ReactionType::class)->create(); + $reacterable1 = factory(User::class)->create(); + $reacterable2 = factory(User::class)->create(); + $reacterable3 = factory(User::class)->create(); + $reactable1 = factory(Article::class)->create(); + $reactable2 = factory(Article::class)->create(); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType2->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable3->getLoveReacter()->getId(), + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType1->getId(), + 'reactant_id' => $reactable2->getLoveReactant()->getId(), + 'reacter_id' => $reacterable3->getLoveReacter()->getId(), + ]); + + $reactedToReactable1WithReactionType1 = User::query() + ->whereNotReactedTo($reactable1, $reactionType1->getName()) + ->get(); + $reactedToReactable1WithReactionType2 = User::query() + ->whereNotReactedTo($reactable1, $reactionType2->getName()) + ->get(); + $reactedToReactable2WithReactionType1 = User::query() + ->whereNotReactedTo($reactable2, $reactionType1->getName()) + ->get(); + $reactedToReactable2WithReactionType2 = User::query() + ->whereNotReactedTo($reactable2, $reactionType2->getName()) + ->get(); + + $this->assertSame([ + $reacterable2->getKey(), + ], $reactedToReactable1WithReactionType1->pluck('id')->toArray()); + $this->assertSame([ + $reacterable1->getKey(), + $reacterable3->getKey(), + ], $reactedToReactable1WithReactionType2->pluck('id')->toArray()); + $this->assertSame([ + $reacterable1->getKey(), + ], $reactedToReactable2WithReactionType1->pluck('id')->toArray()); + $this->assertSame([ + $reacterable2->getKey(), + $reacterable3->getKey(), + ], $reactedToReactable2WithReactionType2->pluck('id')->toArray()); + } + + /** @test */ + public function it_can_scope_reacted_to_reactable_between_datetime_range(): void + { + factory(Reacter::class)->create(); // Needed to has not same ids with Reacter + $reactionType = factory(ReactionType::class)->create(); + $reacterable1 = factory(User::class)->create(); + $reacterable2 = factory(User::class)->create(); + $reacterable3 = factory(User::class)->create(); + $reacterable4 = factory(User::class)->create(); + $reactable1 = factory(Article::class)->create(); + $reactedAt1 = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2022-03-27 23:59:59'); + $reactedAt2 = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2022-03-28 00:00:00'); + $reactedAt3 = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2022-03-28 23:59:59'); + $reactedAt4 = DateTimeImmutable::createFromFormat('Y-m-d H:i:s', '2022-03-29 00:00:00'); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable1->getLoveReacter()->getId(), + 'created_at' => $reactedAt1, + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable2->getLoveReacter()->getId(), + 'created_at' => $reactedAt2, + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable3->getLoveReacter()->getId(), + 'created_at' => $reactedAt3, + ]); + factory(Reaction::class)->create([ + 'reaction_type_id' => $reactionType->getId(), + 'reactant_id' => $reactable1->getLoveReactant()->getId(), + 'reacter_id' => $reacterable4->getLoveReacter()->getId(), + 'created_at' => $reactedAt4, + ]); + + $reactedToReactable = User::query() + ->whereReactedToBetween($reactable1, $reactedAt2, $reactedAt3) + ->get(); + + $this->assertSame([ + $reacterable2->getKey(), + $reacterable3->getKey(), + ], $reactedToReactable->pluck('id')->toArray()); + } +} From bcd0f580cbee5bdcde6563aa91f766321faf9b09 Mon Sep 17 00:00:00 2001 From: Anton Komarev Date: Sun, 8 Jan 2023 14:21:49 +0300 Subject: [PATCH 2/3] Upgrade guide --- UPGRADING.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/UPGRADING.md b/UPGRADING.md index 1fad5635..d939c85a 100644 --- a/UPGRADING.md +++ b/UPGRADING.md @@ -11,6 +11,8 @@ Release v9 has new Eloquent model local scopes approach described in ([#226](https://github.com/cybercog/laravel-love/discussions/226#discussioncomment-4612667)). +### Scopes breaking changes + Reactable trait methods `scopeWhereReactedBy`, `scopeWhereNotReactedBy`, `scopeJoinReactionCounterOfType`, `scopeJoinReactionTotal` were moved to `ReactableEloquentBuilderTrait`. @@ -37,6 +39,17 @@ class UserEloquentBuilder extends \Illuminate\Database\Eloquent\Builder } ``` +### Console commands breaking changes + +Command `love:recount` does not use `sync` connection by default now. +It uses `queue.default` config value. + +To force run synchronous statistics recount use `--queue-connection=sync` option. + +```shell +php artisan love:recount --model="App\User" --queue-connection=sync +``` + ## From v7 to v8 - All `weight` values are `float` now. Round them to get `integer` values as it was before From 6b524317d5a8c76c542c6cb84e7562dff0ada7ef Mon Sep 17 00:00:00 2001 From: Anton Komarev Date: Fri, 24 Feb 2023 16:05:03 +0300 Subject: [PATCH 3/3] Fix typos --- .../ReactableEloquentBuilderTraitTest.php | 42 +++++++++---------- .../ReacterableEloquentBuilderTraitTest.php | 10 ++--- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/tests/Unit/Reactable/ReactableEloquentBuilderTraitTest.php b/tests/Unit/Reactable/ReactableEloquentBuilderTraitTest.php index f9e147ed..c265017e 100644 --- a/tests/Unit/Reactable/ReactableEloquentBuilderTraitTest.php +++ b/tests/Unit/Reactable/ReactableEloquentBuilderTraitTest.php @@ -26,7 +26,7 @@ final class ReactableEloquentBuilderTraitTest extends TestCase /** @test */ public function it_can_scope_by_reacterable(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType = factory(ReactionType::class)->create(); $reactable1 = factory(Article::class)->create(); $reactable2 = factory(Article::class)->create(); @@ -74,7 +74,7 @@ public function it_can_scope_by_reacterable(): void /** @test */ public function it_can_scope_by_reacterable_and_reaction_type(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType1 = factory(ReactionType::class)->create(); $reactionType2 = factory(ReactionType::class)->create(); $reactable1 = factory(Article::class)->create(); @@ -145,7 +145,7 @@ public function it_can_scope_by_reacterable_and_reaction_type(): void /** @test */ public function it_can_scope_not_reacted_by_reacterable(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType = factory(ReactionType::class)->create(); $reactable1 = factory(Article::class)->create(); $reactable2 = factory(Article::class)->create(); @@ -191,7 +191,7 @@ public function it_can_scope_not_reacted_by_reacterable(): void /** @test */ public function it_can_scope_not_reacted_by_reacterable_and_reaction_type(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType1 = factory(ReactionType::class)->create(); $reactionType2 = factory(ReactionType::class)->create(); $reactable1 = factory(Article::class)->create(); @@ -262,7 +262,7 @@ public function it_can_scope_not_reacted_by_reacterable_and_reaction_type(): voi /** @test */ public function it_can_get_reactables_join_reaction_counter_with_type(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType1 = factory(ReactionType::class)->create([ 'mass' => 2, ]); @@ -334,7 +334,7 @@ public function it_can_get_reactables_join_reaction_counter_with_type(): void /** @test */ public function it_can_get_reactables_join_reaction_counter_with_type_when_type_contains_multiple_words(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType1 = factory(ReactionType::class)->create([ 'name' => 'SuperLike', 'mass' => 2, @@ -407,7 +407,7 @@ public function it_can_get_reactables_join_reaction_counter_with_type_when_type_ /** @test */ public function it_select_default_reactable_columns_on_get_reactable_join_reaction_counter_with_type(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType1 = factory(ReactionType::class)->create(); $reactable1 = factory(Article::class)->create(); $reactable2 = factory(Article::class)->create(); @@ -442,7 +442,7 @@ public function it_select_default_reactable_columns_on_get_reactable_join_reacti /** @test */ public function it_can_select_custom_reactable_columns_on_get_reactable_join_reactions_count_with_type(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType1 = factory(ReactionType::class)->create([ 'mass' => 2, ]); @@ -481,7 +481,7 @@ public function it_can_select_custom_reactable_columns_on_get_reactable_join_rea /** @test */ public function it_can_order_by_total_reactions_count(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType = factory(ReactionType::class)->create(); $reactable1 = factory(Article::class)->create(); $reactable2 = factory(Article::class)->create(); @@ -515,7 +515,7 @@ public function it_can_order_by_total_reactions_count(): void /** @test */ public function it_can_order_by_total_reactions_count_with_custom_alias(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType = factory(ReactionType::class)->create(); $reactable1 = factory(Article::class)->create(); $reactable2 = factory(Article::class)->create(); @@ -549,7 +549,7 @@ public function it_can_order_by_total_reactions_count_with_custom_alias(): void /** @test */ public function it_select_default_reactable_columns_on_order_by_total_reactions_count(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType = factory(ReactionType::class)->create(); $reactable1 = factory(Article::class)->create(); $reactable2 = factory(Article::class)->create(); @@ -582,7 +582,7 @@ public function it_select_default_reactable_columns_on_order_by_total_reactions_ /** @test */ public function it_can_select_custom_reactable_columns_on_order_by_total_reactions_count(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType = factory(ReactionType::class)->create(); $reactable1 = factory(Article::class)->create(); $reactable2 = factory(Article::class)->create(); @@ -621,7 +621,7 @@ public function it_can_select_custom_reactable_columns_on_order_by_total_reactio /** @test */ public function it_can_order_by_reactions_weight(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType = factory(ReactionType::class)->create([ 'mass' => 2, ]); @@ -657,7 +657,7 @@ public function it_can_order_by_reactions_weight(): void /** @test */ public function it_select_default_reactable_columns_on_order_by_reactions_weight(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType = factory(ReactionType::class)->create([ 'mass' => 2, ]); @@ -692,7 +692,7 @@ public function it_select_default_reactable_columns_on_order_by_reactions_weight /** @test */ public function it_can_select_custom_reactable_columns_on_order_by_reactions_weight(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType = factory(ReactionType::class)->create([ 'mass' => 2, ]); @@ -733,7 +733,7 @@ public function it_can_select_custom_reactable_columns_on_order_by_reactions_wei /** @test */ public function it_chain_join_reaction_counter_with_type_and_join_reaction_total(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType1 = factory(ReactionType::class)->create([ 'mass' => 2, ]); @@ -808,7 +808,7 @@ public function it_chain_join_reaction_counter_with_type_and_join_reaction_total /** @test */ public function it_include_reaction_total_null_values_replaced_with_zero(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType1 = factory(ReactionType::class)->create([ 'mass' => 2, ]); @@ -860,7 +860,7 @@ public function it_include_reaction_total_null_values_replaced_with_zero(): void /** @test */ public function it_include_reaction_counter_null_values_replaced_with_zero(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType1 = factory(ReactionType::class)->create([ 'mass' => 2, ]); @@ -914,7 +914,7 @@ public function it_include_reaction_counter_null_values_replaced_with_zero(): vo /** @test */ public function it_include_null_counter_and_total_values_in_chain_join_reaction_counter_with_type_and_join_reaction_total(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType1 = factory(ReactionType::class)->create([ 'mass' => 2, ]); @@ -973,7 +973,7 @@ public function it_include_null_counter_and_total_values_in_chain_join_reaction_ /** @test */ public function it_can_chain_multiple_join_reaction_counter_of_type(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType1 = factory(ReactionType::class)->create([ 'name' => 'Like', 'mass' => 2, @@ -1061,7 +1061,7 @@ public function it_can_chain_multiple_join_reaction_counter_of_type(): void /** @test */ public function it_can_chain_multiple_join_reaction_counter_of_type_with_custom_aliases(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType1 = factory(ReactionType::class)->create([ 'name' => 'Like', 'mass' => 2, diff --git a/tests/Unit/Reacterable/ReacterableEloquentBuilderTraitTest.php b/tests/Unit/Reacterable/ReacterableEloquentBuilderTraitTest.php index a74589bb..f72f4148 100644 --- a/tests/Unit/Reacterable/ReacterableEloquentBuilderTraitTest.php +++ b/tests/Unit/Reacterable/ReacterableEloquentBuilderTraitTest.php @@ -27,7 +27,7 @@ final class ReacterableEloquentBuilderTraitTest extends TestCase /** @test */ public function it_can_scope_reacted_to_reactable(): void { - factory(Reacter::class)->create(); // Needed to has not same ids with Reacter + factory(Reacter::class)->create(); // Needed to have not same ids with Reacter $reactionType = factory(ReactionType::class)->create(); $reacterable1 = factory(User::class)->create(); $reacterable2 = factory(User::class)->create(); @@ -75,7 +75,7 @@ public function it_can_scope_reacted_to_reactable(): void /** @test */ public function it_can_scope_reacted_to_reactable_and_reaction_type(): void { - factory(Reacter::class)->create(); // Needed to has not same ids with Reacter + factory(Reacter::class)->create(); // Needed to have not same ids with Reacter $reactionType1 = factory(ReactionType::class)->create(); $reactionType2 = factory(ReactionType::class)->create(); $reacterable1 = factory(User::class)->create(); @@ -146,7 +146,7 @@ public function it_can_scope_reacted_to_reactable_and_reaction_type(): void /** @test */ public function it_can_scope_not_reacted_to_reactable(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType = factory(ReactionType::class)->create(); $reacterable1 = factory(User::class)->create(); $reacterable2 = factory(User::class)->create(); @@ -192,7 +192,7 @@ public function it_can_scope_not_reacted_to_reactable(): void /** @test */ public function it_can_scope_not_reacted_to_reactable_and_reaction_type(): void { - factory(Reactant::class)->create(); // Needed to has not same ids with Reactant + factory(Reactant::class)->create(); // Needed to have not same ids with Reactant $reactionType1 = factory(ReactionType::class)->create(); $reactionType2 = factory(ReactionType::class)->create(); $reacterable1 = factory(User::class)->create(); @@ -263,7 +263,7 @@ public function it_can_scope_not_reacted_to_reactable_and_reaction_type(): void /** @test */ public function it_can_scope_reacted_to_reactable_between_datetime_range(): void { - factory(Reacter::class)->create(); // Needed to has not same ids with Reacter + factory(Reacter::class)->create(); // Needed to have not same ids with Reacter $reactionType = factory(ReactionType::class)->create(); $reacterable1 = factory(User::class)->create(); $reacterable2 = factory(User::class)->create();