Add unique constraint to categories table and update factory data

This commit is contained in:
Víctor Falcón 2025-12-01 11:19:16 +01:00
parent 2b6acf49d8
commit ac95fed57d
4 changed files with 66 additions and 1 deletions

View File

@ -11,6 +11,10 @@ class CreateDefaultCategories
*/
public function handle(User $user): void
{
if ($user->categories()->exists()) {
return;
}
$defaultCategories = self::getDefaultCategories();
foreach ($defaultCategories as $category) {

View File

@ -18,7 +18,7 @@ class CategoryFactory extends Factory
public function definition(): array
{
return [
'name' => fake()->randomElement(['Food', 'Transport', 'Entertainment', 'Shopping', 'Healthcare', 'Utilities', 'Travel', 'Education']),
'name' => fake()->unique()->randomElement(['Food', 'Transport', 'Entertainment', 'Shopping', 'Healthcare', 'Utilities', 'Travel', 'Education', 'Bills', 'Investments', 'Savings', 'Insurance', 'Gifts', 'Personal Care', 'Sports', 'Hobbies', 'Subscriptions', 'Dining', 'Groceries', 'Clothing']),
'icon' => fake()->randomElement(['AlertCircle', 'AlertTriangle', 'ArrowDownCircle', 'ArrowLeftRight', 'ArrowUpCircle', 'Baby', 'Banknote', 'Briefcase', 'Building', 'Building2', 'Car', 'Clock', 'CreditCard', 'Dices', 'FileText', 'Gift', 'GraduationCap', 'HandHeart', 'Heart', 'HelpCircle', 'Home', 'Landmark', 'Mail', 'PiggyBank', 'Plane', 'Receipt', 'ReceiptText', 'Repeat', 'RotateCcw', 'Scale', 'Shield', 'ShieldCheck', 'ShoppingBag', 'TrendingUp', 'Undo2', 'Users', 'Users2', 'Utensils', 'Wallet']),
'color' => fake()->randomElement(['amber', 'blue', 'cyan', 'emerald', 'gray', 'green', 'indigo', 'orange', 'pink', 'purple', 'red', 'slate', 'teal', 'yellow']),
'user_id' => User::factory(),

View File

@ -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('categories', function (Blueprint $table) {
$table->unique(['user_id', 'name']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('categories', function (Blueprint $table) {
$table->dropUnique(['user_id', 'name']);
});
}
};

View File

@ -188,3 +188,36 @@ test('default categories are created when user registers', function () {
$categoryNames = $user->categories->pluck('name')->toArray();
expect($categoryNames)->toContain('Food', 'Transportation', 'Salary', 'Insurance');
});
test('default categories are not created twice for the same user', function () {
$user = User::factory()->create();
$service = new \App\Actions\CreateDefaultCategories;
$service->handle($user);
expect($user->categories()->count())->toBe(63);
$service->handle($user);
expect($user->categories()->count())->toBe(63);
});
test('category names are unique per user', function () {
$user = User::factory()->create();
$category = $user->categories()->create([
'name' => 'Test Category',
'icon' => 'Tag',
'color' => 'red',
]);
expect($category)->toBeInstanceOf(\App\Models\Category::class);
$this->expectException(\Illuminate\Database\UniqueConstraintViolationException::class);
$user->categories()->create([
'name' => 'Test Category',
'icon' => 'Tag',
'color' => 'blue',
]);
});