Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

#38 - Extend eloquent tools #42

Merged
merged 12 commits into from
Jun 28, 2024
145 changes: 140 additions & 5 deletions src/Features/Traits/Eloquent.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,147 @@

namespace Blumilk\BLT\Features\Traits;

use Behat\Gherkin\Node\TableNode;
use Blumilk\BLT\LaravelRelations;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use PHPUnit\Framework\Assert;

trait Eloquent
{
/**
* @Given there is :count :model object in database
* @Given there should be :count :model object in database
* @Given there are :count :model objects in database
* @Given there should be :count :model objects in database
* @Given there is a model :model in the database:
* @Given there is a :model in the database:
*/
public function thereAreModelsInDatabase(string $model, int $count): void
public function seedModelInTheDatabase(string $model, ?TableNode $table = null): void
{
$modelClass = $this->recognizeModelClass($model);
PiotrFedak marked this conversation as resolved.
Show resolved Hide resolved
$attributes = $table ? $table->getRowsHash() : [];

if (method_exists($modelClass, "factory")) {
$modelClass::factory()->create($attributes);
} else {
$modelClass::create($attributes);
}
}

/**
* @Then the model :model exists in the database
*/
public function assertModelExistsInTheDatabase(string $model): void
{
$modelClass = $this->recognizeModelClass($model);

Assert::assertTrue($modelClass::query()->exists(), "The model $model does not exist in the database.");
}

/**
* @Given there are :count :model objects in the database
* @Given there are :count :model in the database
*/
public function thereAreModelsInTheDatabase(string $model, int $count): void
{
$modelClass = $this->recognizeModelClass($model);
$existingCount = $modelClass::query()->count();

if ($existingCount < $count) {
$modelClass::factory()->count($count - $existingCount)->create();
}

Assert::assertEquals($count, $modelClass::query()->count());
}

/**
* @Then the model :model1 has many :model2
*/
public function theModelHasMany(string $model1, string $model2): void
{
$model1Class = $this->recognizeModelClass($model1);
$relation = Str::plural($model2);
$instance = $model1Class::first() ?: $model1Class::factory()->create();

Assert::assertTrue(
method_exists($instance, $relation),
"The model $model1 does not have a $relation relation method.",
);

$this->assertRelation($instance, $relation, LaravelRelations::HAS_MANY);
}

/**
* @Then the model :model1 belongs to :model2
*/
public function theModelBelongsTo(string $model1, string $model2): void
{
$model1Class = $this->recognizeModelClass($model1);
$relation = Str::singular($model2);
$instance = $model1Class::first() ?: $model1Class::factory()->create();

Assert::assertTrue(
method_exists($instance, $relation),
"The model $model1 does not have a $relation relation method.",
);

$this->assertRelation($instance, $relation, LaravelRelations::BELONGS_TO);
}

/**
* @Then the model :model1 has one :model2
*/
public function theModelHasOne(string $model1, string $model2): void
{
$model1Class = $this->recognizeModelClass($model1);
$relation = Str::singular($model2);
$instance = $model1Class::first() ?: $model1Class::factory()->create();

Assert::assertTrue(
method_exists($instance, $relation),
"The model $model1 does not have a $relation relation method.",
);

$this->assertRelation($instance, $relation, LaravelRelations::HAS_ONE);
}

/**
* @Then the model :model1 belongs to many :model2
*/
public function theModelBelongsToMany(string $model1, string $model2): void
{
$model1Class = $this->recognizeModelClass($model1);
$relation = Str::plural($model2);
$instance = $model1Class::first() ?: $model1Class::factory()->create();

Assert::assertTrue(
method_exists($instance, $relation),
"The model $model1 does not have a $relation relation method.",
);

$this->assertRelation($instance, $relation, LaravelRelations::BELONGS_TO_MANY);
}

/**
* @Then the model :model1 has :count related :model2
*/
public function theModelHasExpectedNumberOfRelated(string $model1, string $model2, int $count): void
{
$model1Class = $this->recognizeModelClass($model1);
$relation = Str::plural($model2);
$instance = $model1Class::first() ?: $model1Class::factory()->create();

Assert::assertTrue(
method_exists($instance, $relation),
"The model $model1 does not have a $relation relation method.",
);

$relatedCount = $instance->{$relation}()->count();

Assert::assertEquals(
$count,
$relatedCount,
"The model $model1 does not have $count related $relation.",
);
}

protected function getModelNamespace(): string
{
return "App\\Models\\";
Expand All @@ -36,4 +160,15 @@ protected function recognizeModelClass(string $model): string

return $this->getModelNamespace() . $model;
}

protected function assertRelation(Model $instance, string $relation, string $relationType): void
{
$related = $instance->{$relation}();

Assert::assertInstanceOf(
$relationType,
$related,
"The relation $relation is not of type $relationType.",
);
}
}
13 changes: 13 additions & 0 deletions src/LaravelRelations.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace Blumilk\BLT;

class LaravelRelations
{
public const HAS_MANY = 'Illuminate\Database\Eloquent\Relations\HasMany';
public const BELONGS_TO = 'Illuminate\Database\Eloquent\Relations\BelongsTo';
public const HAS_ONE = 'Illuminate\Database\Eloquent\Relations\HasOne';
public const BELONGS_TO_MANY = 'Illuminate\Database\Eloquent\Relations\BelongsToMany';
}
Loading