app/tests/Unit/Actions/User/CreateUserActionTest.php

238 lines
No EOL
6.6 KiB
PHP

<?php
namespace Tests\Unit\Actions\User;
use App\Actions\User\CreateUserAction;
use App\Models\Planner;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Log;
use Tests\TestCase;
class CreateUserActionTest extends TestCase
{
use RefreshDatabase;
private CreateUserAction $action;
private Planner $planner;
protected function setUp(): void
{
parent::setUp();
$this->action = new CreateUserAction();
// Create a planner for testing
$this->planner = Planner::factory()->create();
}
public function test_it_can_create_a_user_successfully(): void
{
// Arrange
$userData = [
'name' => 'Test User',
'planner_id' => $this->planner->id,
];
// Act
$user = $this->action->execute($userData);
// Assert
$this->assertInstanceOf(User::class, $user);
$this->assertEquals('Test User', $user->name);
$this->assertEquals($this->planner->id, $user->planner_id);
$this->assertDatabaseHas('users', [
'id' => $user->id,
'name' => 'Test User',
'planner_id' => $this->planner->id,
]);
}
public function test_it_throws_exception_when_name_is_empty(): void
{
// Arrange
$userData = [
'name' => '',
'planner_id' => $this->planner->id,
];
// Act & Assert
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Name is required');
$this->action->execute($userData);
// Verify no user was created
$this->assertDatabaseMissing('users', [
'planner_id' => $this->planner->id,
]);
}
public function test_it_throws_exception_when_name_is_missing(): void
{
// Arrange
$userData = [
'planner_id' => $this->planner->id,
];
// Act & Assert
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Name is required');
$this->action->execute($userData);
}
public function test_it_throws_exception_when_planner_id_is_empty(): void
{
// Arrange
$userData = [
'name' => 'Test User',
'planner_id' => '',
];
// Act & Assert
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Planner ID is required');
$this->action->execute($userData);
}
public function test_it_throws_exception_when_planner_id_is_missing(): void
{
// Arrange
$userData = [
'name' => 'Test User',
];
// Act & Assert
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Planner ID is required');
$this->action->execute($userData);
}
public function test_it_logs_creation_process(): void
{
// Arrange
Log::spy();
$userData = [
'name' => 'Test User',
'planner_id' => $this->planner->id,
];
// Act
$user = $this->action->execute($userData);
// Assert
Log::shouldHaveReceived('info')
->with('CreateUserAction: Starting user creation', [
'name' => 'Test User',
'planner_id' => $this->planner->id,
]);
Log::shouldHaveReceived('info')
->with('CreateUserAction: User successfully created', [
'user_id' => $user->id,
'name' => 'Test User',
'planner_id' => $this->planner->id,
]);
}
public function test_it_handles_database_transaction_rollback_on_failure(): void
{
// Arrange
$userData = [
'name' => 'Test User',
'planner_id' => 999999, // Non-existent planner ID should cause foreign key constraint error
];
// Act & Assert
$this->expectException(\Exception::class);
try {
$this->action->execute($userData);
} catch (\Exception $e) {
// Verify no user was created (transaction rolled back)
$this->assertDatabaseMissing('users', [
'name' => 'Test User',
]);
throw $e;
}
}
public function test_it_logs_errors_on_failure(): void
{
// Arrange
Log::spy();
$userData = [
'name' => 'Test User',
'planner_id' => 999999, // Non-existent planner ID
];
// Act & Assert
try {
$this->action->execute($userData);
} catch (\Exception $e) {
// Expected
}
// Assert
Log::shouldHaveReceived('error')
->with('CreateUserAction: User creation failed', \Mockery::on(function ($data) {
return $data['name'] === 'Test User' &&
$data['planner_id'] === 999999 &&
isset($data['error']) &&
isset($data['trace']);
}));
}
public function test_it_creates_user_with_whitespace_trimmed_name(): void
{
// Arrange
$userData = [
'name' => ' Test User ',
'planner_id' => $this->planner->id,
];
// Act
$user = $this->action->execute($userData);
// Assert
$this->assertEquals(' Test User ', $user->name); // Should preserve original data as passed
$this->assertDatabaseHas('users', [
'id' => $user->id,
'name' => ' Test User ',
'planner_id' => $this->planner->id,
]);
}
public function test_it_can_create_multiple_users_with_same_planner(): void
{
// Arrange
$userData1 = [
'name' => 'User One',
'planner_id' => $this->planner->id,
];
$userData2 = [
'name' => 'User Two',
'planner_id' => $this->planner->id,
];
// Act
$user1 = $this->action->execute($userData1);
$user2 = $this->action->execute($userData2);
// Assert
$this->assertNotEquals($user1->id, $user2->id);
$this->assertEquals($this->planner->id, $user1->planner_id);
$this->assertEquals($this->planner->id, $user2->planner_id);
$this->assertDatabaseHas('users', ['name' => 'User One']);
$this->assertDatabaseHas('users', ['name' => 'User Two']);
}
protected function tearDown(): void
{
\Mockery::close();
parent::tearDown();
}
}