Skip to content

Commit

Permalink
feature: add pocket domain
Browse files Browse the repository at this point in the history
  • Loading branch information
mascam97 committed Dec 17, 2023
1 parent abab4a1 commit f1772a7
Show file tree
Hide file tree
Showing 9 changed files with 228 additions and 0 deletions.
20 changes: 20 additions & 0 deletions database/factories/DBPocketFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace Database\Factories;

use Domain\Pockets\Models\Pocket;
use Illuminate\Database\Eloquent\Factories\Factory;

class DBPocketFactory extends Factory
{
protected $model = Pocket::class;

public function definition(): array
{
return [
// TODO: balance should be added by transactions
'balance' => random_int(0, 100000),
'currency' => 'USD',
];
}
}
29 changes: 29 additions & 0 deletions database/migrations/2023_12_17_201022_create_pockets_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

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

return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('pockets', function (Blueprint $table) {
$table->id();
$table->bigInteger('balance')->default(0);
$table->char('currency', 3);
$table->softDeletes();
$table->timestamps();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('pockets');
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

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

return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->foreignId('pocket_id')->nullable()->after('id')->constrained();
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropForeign(['pocket_id']);
$table->dropColumn('pocket_id');
});
}
};
33 changes: 33 additions & 0 deletions src/Domain/Pockets/Factories/PocketFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Domain\Pockets\Factories;

use Domain\Pockets\Models\Pocket;
use Illuminate\Database\Eloquent\Collection;

class PocketFactory
{
private array $properties = [];

private ?int $balance = null;

public function setBalance(int $balance): self
{
$this->balance = $balance;

return $this;
}

public function create(array $extra = []): Pocket|Collection
{
if (! $this->balance) {
/** @var Pocket $pocket */
$pocket = Pocket::factory()->create(array_merge($this->properties, $extra));
} else {
/** @var Collection $pocket */
$pocket = Pocket::factory($this->balance)->create(array_merge($this->properties, $extra));
}

return $pocket;
}
}
52 changes: 52 additions & 0 deletions src/Domain/Pockets/Models/Pocket.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace Domain\Pockets\Models;

use Database\Factories\DBPocketFactory;
use Domain\Pockets\QueryBuilders\PocketQueryBuilder;
use Domain\Users\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Carbon;

/**
* @property-read int $id
*
* @property int $balance
* @property string $currency
* @property Carbon $created_at
* @property Carbon $updated_at
* @property ?Carbon $deleted_at
*
* @property-read User $user
*
* @method static DBPocketFactory factory(...$parameters)
* @method static PocketQueryBuilder query()
*/
class Pocket extends Model
{
use HasFactory;
use SoftDeletes;

protected $casts = [
'balance' => 'int',
];

public function newEloquentBuilder($query): PocketQueryBuilder
{
return new PocketQueryBuilder($query);
}

protected static function newFactory(): Factory
{
return DBPocketFactory::new();
}

public function user(): HasOne
{
return $this->hasOne(User::class);
}
}
31 changes: 31 additions & 0 deletions src/Domain/Pockets/QueryBuilders/PocketQueryBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Domain\Pockets\QueryBuilders;

use Domain\Pockets\Models\Pocket;
use Domain\Users\Models\User;
use Domain\Users\QueryBuilders\UserQueryBuilder;
use Illuminate\Database\Eloquent\Builder;

/**
* @method select($columns = ['*'])
* @method count()
* @method Pocket firstOrFail($columns = ['*'])
*/
class PocketQueryBuilder extends Builder
{
public function whereId(int $id): self
{
return $this->where('id', $id);
}

public function whereUser(User $user): self
{
return $this->whereHas('user', fn (UserQueryBuilder $query) => $query->whereId($user->getKey()));
}

public function whereCurrency(string $currency): self
{
return $this->where('currency', $currency);
}
}
10 changes: 10 additions & 0 deletions src/Domain/Users/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Domain\Users\Models;

use Database\Factories\DBUserFactory;
use Domain\Pockets\Models\Pocket;
use Domain\Quotes\Models\Quote;
use Domain\Rating\Contracts\Rates;
use Domain\Rating\Utils\CanRate;
Expand All @@ -11,7 +12,9 @@
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
Expand All @@ -22,6 +25,7 @@
/**
* @property-read int $id
*
* @property int $pocket_id
* @property string $name
* @property string $email
* @property string $password
Expand All @@ -38,6 +42,7 @@
* @property ?int $roles_count
*
* @property-read HasMany $quotes
* @property-read HasOne $pocket
*
* @method static DBUserFactory factory(...$parameters)
* @method static UserQueryBuilder query()
Expand Down Expand Up @@ -80,6 +85,11 @@ public function quotes(): HasMany
return $this->hasMany(Quote::class);
}

public function pocket(): BelongsTo
{
return $this->belongsTo(Pocket::class);
}

/**
* Create a new factory instance for the model.
*/
Expand Down
15 changes: 15 additions & 0 deletions tests/Unit/Pockets/Models/PocketTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

use Domain\Pockets\Models\Pocket;
use Domain\Users\Models\User;

it('can get user', function () {
$user = User::factory()->create();
/** @var Pocket $pocket */
$pocket = Pocket::factory()->create(['user_id' => $user->id]);

$user->pocket()->associate($pocket);
$pocket->refresh();

expect($pocket->user()->is($user))->toBeTrue();
});
10 changes: 10 additions & 0 deletions tests/Unit/Users/Models/UserTest.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use Domain\Pockets\Models\Pocket;
use Domain\Users\Models\User;
use Illuminate\Database\Eloquent\Collection;

Expand All @@ -10,3 +11,12 @@

expect($user->quotes)->toBeInstanceOf(Collection::class);
});

it('get pocket as single model', function () {
$user = new User();
$pocket = new Pocket();

$user->pocket()->associate($pocket);

expect($user->pocket)->toBeInstanceOf(Pocket::class);
});

0 comments on commit f1772a7

Please sign in to comment.